Tastypie-django自定义错误处理

时间:2012-01-10 17:27:13

标签: django error-handling tastypie

我想返回一些JSON响应,而不是仅返回带有错误代码的标头。在tastypie中有办法处理这样的错误吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:4)

您可以覆盖tastypie的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是否为TastypieError的实例来捕获所有Tastypie错误,并返回JSON响应,并显示消息“抱歉,无法处理此请求。”。如果它是一个不同的例外,我使用_handle_500调用父super(),这将在开发模式下创建一个django错误页面,或在生产模式下创建send_admins()

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

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

实际上我认为在Tastypie中应该有一个更好/更清晰的方法来做这个,所以我在他们的github上opened a ticket