2012-01-10 78 views
8

我想返回一些JSON响应而不是仅仅返回带有错误代码的头。 tastypie有没有办法处理这样的错误?Tastypie-django自定义错误处理

+0

最终发现它。如果有其他人需要,这是一个很好的资源。 https://gist.github.com/1116962 – 2012-01-10 23:43:22

+0

如果可以,请清理它并将其作为答复来帮助社区 – Dave 2012-01-27 22:45:05

回答

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 
3

你可以覆盖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) 

在这种情况下,我通过检查exceptionTastypieError一个实例,并在该消息返回JSON效应初探“对不起,这个要求能抓住所有Tastypie错误不被处理“。如果这是一个不同的例外,我使用super()调用父_handle_500,这将在开发模式下创建一个django错误页面,或者在生产模式下创建一个send_admins()

如果您想针对特定异常具有特定的JSON响应,只需对特定异常执行isinstance()检查即可。这里是所有Tastypie例外:

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

其实我觉得应该有Tastypie做这更好/更清洁的方式,所以我opened a ticket他们的github上。