0

I am trying to validate whether password1, password2 are matching not using object level validation because it is executed after all field level validations, but validate_field only accepts one value. How can I implement the following in rest framework?

def validate_password2(self, data):
        print 'validating...'
        password1, password2 = data['password1'], data['password2']           
        if password1 and password2 and password1 != password2: 
              raise serializers.ValidationError('The two passwords do not match.')         
        return password2

And when errors occur, the data in the form are cleared. How can I retain the input data even when the errors occur like django form.fields?

2 Answers 2

4

Instead of adding field-level validation, add this check to your object-level validation because you require access to multiple fields.

Even the DRF docs define this:

Object-level validation

To do any other validation that requires access to multiple fields, add a method called .validate() to your Serializer subclass. This method takes a single argument, which is a dictionary of field values. It should raise a ValidationError if necessary, or just return the validated values.

You can just do the following:

def validate(self, data):
    ...
    password1 = data['password1']
    password2 = data['password2']
    if password1 and password2 and password1 != password2:
        raise serializers.ValidationError('The two passwords do not match.')
    ....
    return data

Also to access the initial data when errors have occured, you can use your_serializer.initial_data.

Sign up to request clarification or add additional context in comments.

3 Comments

First, thanks for the answer. If I have multiple fields that needs different validations then I have to add all that stuff in validate function. right ? and what will happen to built in validations like email validation. What if I access initial_data in field level validator ? is it bad practice ?
If your multiple fields validations depend on each other, then you have to do that in validate() function, otherwise, do that in validate_<fieldname>() function. The built-in validations will hapen regardless of your custom validation, so you don't need to worry about it. If you really need the initial_data for doing some validations, then you should use it.
Thanks, much helpful. Main concern was overriding validate will or will not override built-in validations. But now, clear.
0

Something like this for validating password in DRF

def validate_password2(self, attrs, source):
    """
    password_confirmation check
    """
    password_confirmation = attrs[source]
    password = attrs['password1']

    if password_confirmation != password:
        raise serializers.ValidationError('password didnot match')

    return attrs

2 Comments

I am using DRF v 3.1+, so does that accept attrs? As I know of, it only accept one value, the value of the field.
No idea regarding DRF 3.1+,please check this might help stackoverflow.com/questions/27591574/… stackoverflow.com/questions/27591184/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.