Saltar al contenido

Manejo de excepciones de errores de la base de datos de Django Rest Framework

No busques más por todo internet ya que has llegado al lugar exacto, contamos con la solución que necesitas hallar pero sin liarte.

Solución:

Si bien anular la vista genérica es una solución completamente válida, creo que una mejor solución es utilizar la opción de Django REST Frameworks para implementar el manejo personalizado de excepciones. Para ello, crea una función de controlador que convierte las excepciones generadas en las vistas de la API en objetos de respuesta. Para hacer esto, todo lo que tiene que hacer es decirle a Django REST Framework dónde está su controlador personalizado anulándolo en la configuración:

REST_FRAMEWORK = 'EXCEPTION_HANDLER':'my_project.my_app.utils.custom_exception_handler'

Dentro del archivo especificado (my_project/my_app/utils.py en este caso) entonces haría algo como lo siguiente:

from __future__ import unicode_literals
from django.db import IntegrityError
from rest_framework.views import Response, exception_handler
from rest_framework import status


def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first to get the standard error response.
    response = exception_handler(exc, context)

    # if there is an IntegrityError and the error response hasn't already been generated
    if isinstance(exc, IntegrityError) and not response:
        response = Response(
            
                'message': 'It seems there is a conflict between the data you are trying to save and your current '
                           'data. Please review your entries and try again.'
            ,
            status=status.HTTP_400_BAD_REQUEST
        )

    return response

Como dicen los documentos, vale la pena señalar “que el controlador de excepciones solo se llamará para las respuestas generadas por las excepciones planteadas”. (es decir, solo cuando haces lo siguiente: serializer.is_valid(raise_exception=True)). Sin embargo, esto solo importa si está llamando serializer.is_valid() usted mismo ya que “las vistas genéricas usan el indicador raise_exception=True, lo que significa que puede anular el estilo de las respuestas de error de validación globalmente en su API. Para hacerlo, use un controlador de excepciones personalizado, como se describe anteriormente”. Además, solo quiero señalar que si desea especificar un personalizado IntegrityError mensaje en una vista determinada más adelante, siempre puede anular la vista genérica como lo demuestran las otras respuestas y el controlador de excepciones personalizado no insertará el mensaje predeterminado ya que response ya no será None.

para hacer esto usando rest_framework adecuado (con una respuesta de estilo de marco de descanso):

from django.db import IntegrityError
from rest_framework import status
from rest_framework.generics import ListCreateAPIView
from rest_framework.response import Response

class MyListCreateAPIView(ListCreateAPIView):
    def create(self, request, *args, **kwargs):
        try:
            return super(ListCreateAPIView, self).create(request, *args, **kwargs)
        except IntegrityError:
            content = 'error': 'IntegrityError'
            return Response(content, status=status.HTTP_400_BAD_REQUEST)

Aquí hay una lista de HTTP 400 disponibles códigos de estado

deberías extender ListCreateAPIView y atrapar el IntegrityError y manejarlo devolviendo un bad_request:

from django.views.defaults import bad_request
from rest_framework.generics import ListCreateAPIView

class MyListCreateAPIView(ListCreateAPIView):

    def create(self, request, *args, **kwargs):
        try:
            return super(ListCreateAPIView,self).create(request, *args, **kwargs)
        except IntegrityError:
            return bad_request(request)

Curiosamente podrías plantear un SuspiciousOperation en lugar de devolver bad_request explícitamente:

        except IntegrityError:
            from django.core.exceptions import SuspiciousOperation
            raise SuspiciousOperation

Entonces django devolverá un 400 BAD REQUEST.

valoraciones y comentarios

Si eres capaz, tienes el poder dejar una división acerca de qué te ha parecido este tutorial.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *