integrate django password validators with django rest framework validate_password integrate django password validators with django rest framework validate_password django django

integrate django password validators with django rest framework validate_password


Like you mentioned, when you validate the password in validate_password method using UserAttributeSimilarityValidator validator, you don't have the user object.

What I suggest that instead of doing field-level validation, you shall perform object-level validation by implementing validate method on the serializer:

import sysfrom django.core import exceptionsimport django.contrib.auth.password_validation as validatorsclass RegisterUserSerializer(serializers.ModelSerializer):     # rest of the code     def validate(self, data):         # here data has all the fields which have validated values         # so we can create a User instance out of it         user = User(**data)         # get the password from the data         password = data.get('password')         errors = dict()          try:             # validate the password and catch the exception             validators.validate_password(password=password, user=User)         # the exception raised here is different than serializers.ValidationError         except exceptions.ValidationError as e:             errors['password'] = list(e.messages)         if errors:             raise serializers.ValidationError(errors)         return super(RegisterUserSerializer, self).validate(data)


You can access the user object through self.instance on the serializer object, even when doing field-level validation. Something like this should work:

 from django.contrib.auth import password_validation def validate_password(self, value):    password_validation.validate_password(value, self.instance)    return value


Use Serializers! Have a validate_fieldname method!

class UserSerializer(serializers.ModelSerializer):    class Meta:        model = User        fields = (            'id', 'username', 'password', 'first_name', 'last_name', 'email'        )        extra_kwargs = {            'password': {'write_only': True},            'username': {'read_only': True}        }    def validate_password(self, value):        try:            validate_password(value)        except ValidationError as exc:            raise serializers.ValidationError(str(exc))        return value    def create(self, validated_data):        user = super().create(validated_data)        user.set_password(validated_data['password'])        user.is_active = False        user.save()        return user    def update(self, instance, validated_data):        user = super().update(instance, validated_data)        if 'password' in validated_data:            user.set_password(validated_data['password'])            user.save()        return user