Django DRF:使序列化程序字段值等于另一个值
我正在创建一个端点来重置密码,并创建了序列化程序、视图,我正在使用django.contrib.auth.forms获取数据并向用户发送电子邮件。 表单要求键入两次新密码,但我想要的是只写入一次,并使Django DRF:使序列化程序字段值等于另一个值,django,django-rest-framework,Django,Django Rest Framework,我正在创建一个端点来重置密码,并创建了序列化程序、视图,我正在使用django.contrib.auth.forms获取数据并向用户发送电子邮件。 表单要求键入两次新密码,但我想要的是只写入一次,并使new\u password2的值等于new\u password1。例如,我想更改Swagger上的密码,但键入两次没有意义,因为它是一个普通的CharField而不是PasswordField 这是serializers.pyResetPasswordConfirm类 class ResetPa
new\u password2
的值等于new\u password1
。例如,我想更改Swagger上的密码,但键入两次没有意义,因为它是一个普通的CharField而不是PasswordField
这是serializers.py
ResetPasswordConfirm类
class ResetPasswordConfirmSerializer(serializers.Serializer):
new_password1 = serializers.CharField(max_length=128)
new_password2 = serializers.CharField(max_length=128)
uid = serializers.CharField()
token = serializers.CharField()
set_password_form_class = SetPasswordForm
def __init__(self, *args, **kwargs):
super(ResetPasswordConfirmSerializer, self).__init__(*args, **kwargs)
self.set_password_form = None
def validate(self, value, *args, **kwargs):
try:
uid = force_text(uid_decoder(value['uid']))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
raise ValidationError({
'uid': ['Invalid value']
})
self.set_password_form = self.set_password_form_class(user=user, data=value)
if not self.set_password_form.is_valid():
raise serializers.ValidationError(self.set_password_form.errors)
if not default_token_generator.check_token(user, value['token']):
raise ValidationError({
'token': ['Invalid value']
})
return value
def save(self, **kwargs):
return self.set_password_form.save()
以及API视图
class ResetPasswordConfirmAPIView(GenericAPIView):
serializer_class = ResetPasswordConfirmSerializer
permission_classes = (AllowAny,)
@method_decorator(csrf_protect)
def dispatch(self, *args, **kwargs):
return super(ResetPasswordConfirmAPIView, self).dispatch(*args, **kwargs)
def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response({
'detail': _("Password has been reset"),
}, status=status.HTTP_200_OK)
我尝试了不同的方法来创建新密码2,但是我遇到了错误。有什么建议吗?您只能在序列化程序中保留
新密码1
,并更新发送到验证方法中表单的数据:
class ResetPasswordConfirmSerializer(serializers.Serializer):
new_password1 = serializers.CharField(max_length=128)
uid = serializers.CharField()
token = serializers.CharField()
set_password_form_class = SetPasswordForm
def __init__(self, *args, **kwargs):
super(ResetPasswordConfirmSerializer, self).__init__(*args, **kwargs)
self.set_password_form = None
def validate(self, value, *args, **kwargs):
try:
uid = force_text(uid_decoder(value['uid']))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
raise ValidationError({
'uid': ['Invalid value']
})
new_value = value.copy()
new_value['new_password2'] = value['new_password1']
self.set_password_form = self.set_password_form_class(user=user, data=new_value)
if not self.set_password_form.is_valid():
raise serializers.ValidationError(self.set_password_form.errors)
if not default_token_generator.check_token(user, value['token']):
raise ValidationError({
'token': ['Invalid value']
})
return value
def save(self, **kwargs):
return self.set_password_form.save()
但我认为,不使用表单也有可能而且更清楚,您可以使用django的函数来验证密码。我没有测试它,但您可以尝试以下内容:
from django.contrib.auth.password_validation import validate_password
class ResetPasswordConfirmSerializer(serializers.Serializer):
new_password1 = serializers.CharField(max_length=128)
uid = serializers.CharField()
token = serializers.CharField()
def validate(self, value, *args, **kwargs):
try:
uid = force_text(uid_decoder(value['uid']))
user = User.objects.get(pk=uid)
except (TypeError, ValueError, OverflowError, User.DoesNotExist):
raise ValidationError({
'uid': ['Invalid value']
})
if not default_token_generator.check_token(user, value['token']):
raise ValidationError({
'token': ['Invalid value']
})
validate_password(password=value['new_password1'], user=user)
return value
def save(self, **kwargs):
user = User.objects.get(pk=self.validated_data['uid'])
user.set_password(self.validated_data['new_password1'])
user.save()
return user
完美的谢谢。没有考虑复制值并使用新的dict传递到表单。@XhensB不客气!我已经用无格式的方法更新了我的答案。你也可以检查一下。非常有用的答案!:)@XhensB经过一些新的编辑后,我希望它更清晰:)肯定:)现在我正在考虑处理序列化程序中的所有内容