¿Cómo cambiar las respuestas de error de validación en DRF?

Quiero cambiar el JSON, que rest_framework o django devuelve cuando se produce un error de validación.

Usaré una de mis vistas como ejemplo, pero quiero cambiar los mensajes de error para todas mis vistas. Así que digamos que tengo esta vista para iniciar sesión en los usuarios, proporcionar correo electrónico y contraseña. Si estos son correctos, devuelve access_token.

Si publico solo la contraseña, devuelve el error 400:

{"email": ["This field is required."]} 

y si la contraseña y el correo electrónico no coinciden:

 {"detail": ["Unable to log in with provided credentials."]} 

Lo que quiero sería más como

 {"errors": [{"field": "email", "message": "This field is required."}]} {"errors": [{"non-field-error": "Unable to log in with provided credentials."}]} 

Ahora este es mi punto de vista :

 class OurLoginObtainAuthToken(APIView): permission_classes = (AllowAny,) serializer_class = serializers.AuthTokenSerializer model = Token def post(self, request): serializer = self.serializer_class(data=request.DATA) if serializer.is_valid(): #some magic return Response(token) return Response(serializers.errors, status=status.HTTP_400_BAD_REQUEST) 

Puedo acceder al serializador. Los errores y modificarlos, pero parece que solo se puede acceder a los errores de campo de esa manera . ¿Cómo cambiar también los errores de validación creados en el método de validación de mi serializador?

Este es mi serializador (es el mismo serializador que rest_framework.authtoken.serializers.AuthTokenSerializer) pero editado, por lo que la autenticación no requiere nombre de usuario sino correo electrónico:

 class AuthTokenSerializer(serializers.Serializer): email = serializers.CharField() password = serializers.CharField() def validate(self, attrs): email = attrs.get('email') password = attrs.get('password') #print email #print password if email and password: user = authenticate(email=email, password=password) if user: if not user.is_active: msg = _('User account is disabled.') raise ValidationError(msg) attrs['user'] = user return attrs else: msg = _('Unable to log in with provided credentials.') raise ValidationError(msg) else: msg = _('Must include "username" and "password"') raise ValidationError(msg) 

O tal vez hay un enfoque completamente diferente? Estaré muy agradecido por cualquier idea.

La forma más fácil de cambiar el estilo de error a través de todas las vistas en su aplicación es usar siempre serializer.is_valid(raise_exception=True) , y luego implementar un controlador de excepciones personalizado que defina cómo se crea la respuesta de error.

La estructura predeterminada de DRF cuando se manejan errores es algo como esto:

 {"email": ["This field is required."]} 

Y puede cambiar esta estructura según sus necesidades escribiendo un controlador de excepciones personalizado .

Ahora digamos que quieres lograr la siguiente estructura:

 {"errors": [{"field": "email", "message": "This field is required."}]} 

Su controlador de excepciones personalizado podría ser algo como esto:

 from rest_framework.views import exception_handler 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) # Update the structure of the response data. if response is not None: customized_response = {} customized_response['errors'] = [] for key, value in response.data.items(): error = {'field': key, 'message': value} customized_response['errors'].append(error) response.data = customized_response return response