Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Rest Framework custom validation errors

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!

like image 914
Dario Behringer Avatar asked Jan 19 '15 17:01

Dario Behringer


People also ask

How do I create a custom exception in Django REST framework?

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.

How does Django validate data in serializer?

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.

How does Django validate data?

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.


1 Answers

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.

like image 55
Kevin Brown-Silva Avatar answered Nov 13 '22 10:11

Kevin Brown-Silva