【问题标题】:Django Rest Framework - Check Password to Validate FormDjango Rest Framework - 检查密码以验证表单
【发布时间】:2019-04-14 04:25:12
【问题描述】:

我正在尝试通过 DRF 验证表单,但它需要用户输入密码以进行确认。我似乎无法让它工作。这是我当前的视图和序列化器。它用于“更改电子邮件”表单,需要两个字段,电子邮件和用户密码。这是一个单独的电子邮件模型。序列化器:

class UpdateEmailAddressSerializer(serializers.ModelSerializer):

    class Meta:
        model = EmailAddress
        fields = ('email',)

还有 APIView:

class UpdateEmailAPI(APIView):

permission_classes = (IsAuthenticated,)
serializer_class = UpdateEmailAddressSerializer

def post(self, request, user, format=None):
    user = User.objects.get(username=user)
    serializer = UpdateEmailAddressSerializer(data=request.data, instance=user)
    if serializer.is_valid():

        ## logic to check and send email

        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)  

我不确定在哪里放置密码或如何处理它。它来自用户模型本身。当我尝试向 UpdateEmail 序列化程序中的字段添加密码时,它最终以纯文本更新用户密码并使该用户对象无法使用该密码。

我只想检查用户的密码以确认此表单。有没有明显的方法可以做到这一点?

编辑

当我尝试将“密码”带入序列化程序时,错误提示“字段名称 password 对模型 EmailAddress 无效。”因此,当我尝试将其引入时,例如

password = serializers.CharField(required=True)

或尝试:

## UserPasswordSerializer 
class UserPasswordSerializer(serializers.ModelSerializer):

class Meta:
    model = User
    fields = (
        'password',
        )

## In UpdateEmailAddressSerializer
password = UserPasswordSerializer()

在 DRF 上提交表单时出现此错误:

尝试获取字段值时出现 AttributeError password 在序列化程序 UpdateEmailAddressSerializer 上。这 序列化器字段可能命名不正确并且不匹配任何 EmailAddress 实例上的属性或键。原始异常 文本是:“EmailAddress”对象没有属性“密码”

所以它似乎告诉我密码不是正确的电子邮件地址模型的一部分。但我不知道如何简单地检查表单帖子旁边的密码而不使其成为电子邮件地址的一部分。

【问题讨论】:

标签: django django-rest-framework


【解决方案1】:

我认为你可以这样尝试:

class UpdateEmailAddressSerializer(serializers.ModelSerializer):
    password = serializers.CharField(write_only=True)
    class Meta:
        model = EmailAddress
        fields = ('email', 'password',)

    def create(self, validated_data):
       validated_data.pop('password', None)
       return super(UpdateEmailAddressSerializer, self).create(validated_data)

    def update(self, instance, validated_data):
         if instance.check_password(validated_data.get('password')):
               instance.email = validated_data.get('email', instance.email)
         # else throw validation error
         return instance

【讨论】:

  • 我认为密码是您模型的一部分。无论如何,更新我的答案@user3752958
  • 您的回答为我指明了正确的方向。一旦您添加 check_password 方法来创建,它就可以工作(在这种情况下不调用更新)。或者更好的是 validate_password() 方法。专门从初始数据中获取用户对象,然后检查 user.check_password(value)。但是从创建中删除密码是需要的。谢谢。
猜你喜欢
  • 2021-05-16
  • 2020-12-08
  • 2019-11-29
  • 2015-02-19
  • 2018-09-17
  • 2016-05-21
  • 1970-01-01
  • 2021-09-09
  • 1970-01-01
相关资源
最近更新 更多