8

我想返回一些 JSON 响应,而不是只返回带有错误代码的标头。有没有一种方法可以处理这样的错误?

4

2 回答 2

5

最终想通了。如果其他人需要,这里是一个很好的资源。http://gist.github.com/1116962

class YourResource(ModelResource):

    def wrap_view(self, view):
        """
        Wraps views to return custom error codes instead of generic 500's
        """
        @csrf_exempt
        def wrapper(request, *args, **kwargs):
            try:
                callback = getattr(self, view)
                response = callback(request, *args, **kwargs)

                if request.is_ajax():
                    patch_cache_control(response, no_cache=True)

                # response is a HttpResponse object, so follow Django's instructions
                # to change it to your needs before you return it.
                # https://docs.djangoproject.com/en/dev/ref/request-response/
                return response
            except (BadRequest, ApiFieldError), e:
                return HttpBadRequest({'code': 666, 'message':e.args[0]})
            except ValidationError, e:
                # Or do some JSON wrapping around the standard 500
                return HttpBadRequest({'code': 777, 'message':', '.join(e.messages)})
            except Exception, e:
                # Rather than re-raising, we're going to things similar to
                # what Django does. The difference is returning a serialized
                # error message.
                return self._handle_500(request, e)

        return wrapper
于 2012-02-08T16:14:47.823 回答
4

你可以覆盖tastepie的Resource方法_handle_500()。它以下划线开头的事实确实表明这是一种“私有”方法,不应该被覆盖,但我发现它比必须覆盖wrap_view()和复制大量逻辑更干净。

这是我使用它的方式:

from tastypie import http
from tastypie.resources import ModelResource
from tastypie.exceptions import TastypieError

class MyResource(ModelResource):

    class Meta:
        queryset = MyModel.objects.all()
        fields = ('my', 'fields')

    def _handle_500(self, request, exception):

        if isinstance(exception, TastypieError):

            data = {
                'error_message': getattr(
                    settings,
                    'TASTYPIE_CANNED_ERROR',
                    'Sorry, this request could not be processed.'
                ),
            }

            return self.error_response(
                request,
                data,
                response_class=http.HttpApplicationError
            )

        else:
            return super(MyResource, self)._handle_500(request, exception)

exception在这种情况下,我通过检查是否是一个实例来捕获所有 Tastypie 错误,TastypieError并返回带有消息“抱歉,此请求无法处理。”的 JSON 响应。如果是不同的异常,我_handle_500使用调用父级,这将在开发模式或生产模式下super()创建一个 django 错误页面。send_admins()

如果您想对特定异常有特定的 JSON 响应,只需isinstance()检查特定异常即可。以下是所有 Tastypie 的例外情况:

https://github.com/toastdriven/django-tastypie/blob/master/tastypie/exceptions.py

实际上我认为在 Tastypie 中应该有更好/更清洁的方法来做到这一点,所以我在他们的 github 上开了一张票。

于 2013-07-16T13:36:16.950 回答