2012-01-10 11 views
8

Me gustaría devolver algunas respuestas JSON en lugar de simplemente devolver un encabezado con un código de error. ¿Hay alguna manera en tastypie para manejar errores como ese?Tastypie-django manejo de errores personalizados

+0

se resolvió con el tiempo. Aquí hay un buen recurso para mirar, si alguien más lo necesita. https://gist.github.com/1116962 –

+0

Si puede, limpie esto y conviértalo en una respuesta para ayudar a la comunidad – Dave

Respuesta

5

Lo descubrimos eventualmente. Aquí hay un buen recurso para mirar, si alguien más lo necesita. 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

Se podría sobrescribir Resource método _handle_500() de tastypie. El hecho de que comience con un guión bajo indica que este es un método "privado" y no debe sobrescribirse, pero considero que es más limpio que tener que sobrescribir wrap_view() y reproducir mucha lógica.

Esta es la forma en que lo uso:

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) 

En este caso cojo todos los errores Tastypie comprobando si exception es una instancia de TastypieError y devolver una Reponse JSON con el mensaje "Lo sentimos, la presente solicitud no ser procesado ". Si se trata de una excepción diferente, llamo al padre _handle_500 usando super(), que creará una página de error django en modo de desarrollo o send_admins() en modo de producción.

Si desea tener una respuesta JSON específica para una excepción específica, simplemente haga la verificación isinstance() en una excepción específica. Aquí están todas las excepciones Tastypie:

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

En realidad, yo creo que debe haber una manera mejor/más limpia de hacer esto en Tastypie, así que opened a ticket en su github.