Convert Django Validation Errors to DRF compatible Errors
Custom Exception handler for Django Rest Framework
While working with Django+Django Rest Framework, you might have come up in a problem that occurrence of Errors/ValidationErrors from Django Model or some internals will not response a valid json
your API consumer was expecting.
For example: Errors/ValidationErrors from Django Model or some internals will output something like
This looks so ugly (on debug mode only!), but with DEBUG=False
as well, you will get something like
So, let's create up a custom exception handler for Django Rest Framework which will catch exceptions from those above mentioned scenarios and convert them to something much more prettier which can be easily transformed to json
from django.core.exceptions import NON_FIELD_ERRORS as DJ_NON_FIELD_ERRORS
from django.core.exceptions import ValidationError as DjValidationError
from rest_framework.exceptions import ValidationError as DRFValidationError
from rest_framework.views import api_settings
from rest_framework.views import exception_handler as drf_exception_handler
DRF_NON_FIELD_ERRORS = api_settings.NON_FIELD_ERRORS_KEY
def handle(exc, context):
# translate django validation error which ...
# .. causes HTTP 500 status ==> DRF validation which will cause 400 HTTP status
if isinstance(exc, DjValidationError):
data = exc.message_dict
if DJ_NON_FIELD_ERRORS in data:
data[DRF_NON_FIELD_ERRORS] = data[DJ_NON_FIELD_ERRORS]
del data[DJ_NON_FIELD_ERRORS]
exc = DRFValidationError(detail=data)
return drf_exception_handler(exc, context)
and add this exception handler function as your default exception handler on django rest framework settings on your settings.py
file
REST_FRAMEWORK = {
# .....
'EXCEPTION_HANDLER': 'path_to_your_exception_hander'
# ...
}
Now, the internal Django validation error that you raise from models or anywhere maybe will look like this;
Tested on
- Django(3.0.3) and Django Rest Framework(3.11.0)
- Django(4.0.2) and Django Rest Framework(3.13.1)