I've noticed that Django form and model validators should raise a django.core.exceptions.ValidationError
, which is an immediate subclass of Exception
.
In DRF, however, my validator is expected to raise rest_framework.exceptions.ValidationError
, which is not a descendant of Django's (it derives from rest_framework.exceptions.APIException(Exception)
).
Keeping myself DRY, how can I write a validator once, and use it in both, say, Django forms and a DRF serializer?
Here is a related question where DRF does not catch a Django core ValidationError
I'm using django==1.8 and DRF==3.3.2 and I've just written custom validator in my project and have noticed that both django.core and restframework's ValidationError exceptions works equally fine in DRF. I think this is due to this code in rest_framework.fields:
from django.core.exceptions import ValidationError as DjangoValidationError
from rest_framework.exceptions import ValidationError
...
def run_validators(self, value):
"""
Test the given value against all the validators on the field,
and either raise a `ValidationError` or simply return.
"""
errors = []
for validator in self.validators:
if hasattr(validator, 'set_context'):
validator.set_context(self)
try:
validator(value)
except ValidationError as exc:
# If the validation error contains a mapping of fields to
# errors then simply raise it immediately rather than
# attempting to accumulate a list of errors.
if isinstance(exc.detail, dict):
raise
errors.extend(exc.detail)
except DjangoValidationError as exc:
errors.extend(exc.messages)
if errors:
raise ValidationError(errors)
As you can see, both exceptions can be caught by DRF, so you can use django.core.exceptions.ValidationError in both django forms and DRF.