I'm trying to customize the default validation errors of DRF (3.x) for an account model. My goal is to write a validation function in order to send back a customized error message.
I've tried the following:
class AccountSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=False)
class Meta:
model = Account
fields = ('id', 'email', 'password',)
def validate_password(self, value):
"""
Validate Password.
"""
if not value:
raise serializers.ValidationError("Password cannot be empty!")
elif len(value) < 5:
raise serializers.ValidationError("Password to short...")
return value
The the length validation works fine, but the 'password is empty' validation is never thrown because the default error ('password', [u'This field may not be blank.']) is thrown before.
Is there any option to disable default errors or to force validation by my custom function first?
Thanks for help!
Custom exception handlingThe exception handler function should either return a Response object, or return None if the exception cannot be handled. If the handler returns None then the exception will be re-raised and Django will return a standard HTTP 500 'server error' response.
Validation in Django REST framework serializers is handled a little differently to how validation works in Django's ModelForm class. With ModelForm the validation is performed partially on the form, and partially on the model instance. With REST framework the validation is performed entirely on the serializer class.
Django provides built-in methods to validate form data automatically. Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class.
You can override the validation errors on a per-field basis by setting the error_messages
argument when initializing the field. You need to pass a dictionary with the key being the error message name, and the value being the custom text for the error message.
In your case, you are looking to implement two error messages: required
and min_length
. You may also need to override blank
, which is triggering your current error, unless you set allow_blank=True
on the field.
So with those changes, your serializer would become
class AccountSerializer(serializers.ModelSerializer):
password = serializers.CharField(
write_only=True,
required=False,
min_length=5,
error_messages={
"blank": "Password cannot be empty.",
"min_length": "Password too short.",
},
)
class Meta:
model = Account
fields = ('id', 'email', 'password', )
I've replaced your len
check with the min_length
argument on the password field.
This offloads all of your validation to Django REST framework, which should make upgrades easier in the future. You can still override validate_password
if you need additional custom validation, but for now I've removed it since it would be empty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With