I am trying to integrate django validators 1.9 with django rest framework serializers. But the serialized "user" (django rest framework) is incompatible with django validators.
Here are the .py serializers
import django.contrib.auth.password_validation as validators from rest_framework import serializers class RegisterUserSerializer(serializers.ModelSerializer): password = serializers.CharField(style={'input_type': 'password'}, write_only=True) class Meta: model = User fields = ('id', 'username', 'email, 'password') def validate_password(self, data): validators.validate_password(password=data, user=User) return data def create(self, validated_data): user = User.objects.create_user(**validated_data) user.is_active = False user.save() return user
I managed to get MinimumLengthValidator and NumericPasswordValidator correctly, because both function checks do not use "user" when checking. Source code here
Excerpt from django source code:
def validate(self, password, user=None): if password.isdigit(): raise ValidationError( _("This password is entirely numeric."), code='password_entirely_numeric', )
For other validators, such as UserAttributeSimilarityValidator, the function uses another argument "user" when checking ("user" is the django user model, if I'm not mistaken)
Excerpt from django source code:
def validate(self, password, user=None): if not user: return for attribute_name in self.user_attributes: value = getattr(user, attribute_name, None)
How to change serialized user to what django validators (UserAttributeSimilarityValidator) can see
Excerpt from django source code:
def validate(self, password, user=None): if not user: return for attribute_name in self.user_attributes: value = getattr(user, attribute_name, None) if not value or not isinstance(value, string_types): continue
Edit
The Django Rest Framework can get all the built-in Django password checks (but this is how to hack). Here's the problem:
ValidationError value looks like this
[ValidationError (['This password is too short, it must be less than 8 characters.']), ValidationError (['This password is fully Numeric.])]
Validation does not contain a field. Django rest structure treats it as
{ "non_field_errors": [ "This password is too short. It must contain at least 8 characters.", "This password is entirely numeric." ] }
How can I enter a field in raise ValidationError