将django密码验证器与django rest框架validate_password集成 [英] integrate django password validators with django rest framework validate_password
问题描述
我正在尝试集成 django验证器 1.9与django rest框架序列化程序。但是(Django REST框架的)序列化用户与Django验证程序不兼容。
I'm trying to integrate django validators 1.9 with django rest framework serializers. But the serialized 'user' (of django rest framework) is not compatible with the django validators.
这里是serializers.py
Here is the serializers.py
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
我设法g MinimumLengthValidator和NumericPasswordValidator正确,因为两个函数均未在验证中使用用户。源代码是此处
I managed to get MinimumLengthValidator and NumericPasswordValidator correct because both function validate don't use 'user' in validating. Source code is here
摘录自Django源代码:
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',
)
对于其他验证器(如UserAttributeSimilarityValidator),该函数在验证时使用另一个参数 user( user'是django用户模型,如果我没记错的话)
For other validators like UserAttributeSimilarityValidator, the function uses another one argument 'user' in validating ('user' is django User model, if I'm not wrong)
django源代码摘录:
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)
如何将序列化的用户更改为django验证器(UserAttributeSimilarityValidator)可以看到的内容
django源代码的摘录:
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
编辑
Django Rest Framework可以获取Django的所有内置密码验证(但就像黑客一样)。这是一个问题:
Django Rest Framework can get all of Django's built-in password validation (but it's like a hack). Here's a problem:
validationError就是这样
The validationError is like this
[ValidationError([ 此密码太短。它必须至少包含
个8个字符。']),ValidationError(['此密码完全是
个数字。'])]
[ValidationError(['This password is too short. It must contain at least 8 characters.']), ValidationError(['This password is entirely numeric.'])]
验证不包含字段。 Django rest框架将其视为
The validation doesn't contain a field. Django rest framework see it as
{
"non_field_errors": [
"This password is too short. It must contain at least 8 characters.",
"This password is entirely numeric."
]
}
如何在<$ c $处注入字段c> raise ValidationError
推荐答案
就像您提到的那样,当您验证使用
,您没有 UserAttributeSimilarityValidator
验证器的 validate_password
方法中的密码 user
对象。
Like you mentioned, when you validate the password
in validate_password
method using UserAttributeSimilarityValidator
validator, you don't have the user
object.
我建议您执行对象级验证,方法是实现 validate 序列化程序上的code>方法:
What I suggest that instead of doing field-level validation, you shall perform object-level validation by implementing validate
method on the serializer:
import sys
from django.core import exceptions
import django.contrib.auth.password_validation as validators
class 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)
这篇关于将django密码验证器与django rest框架validate_password集成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!