【问题标题】:TypeError: User() got an unexpected keyword argument 'confirm_password'TypeError: User() 得到了一个意外的关键字参数“confirm_password”
【发布时间】:2020-08-20 09:22:17
【问题描述】:

我想将password 字段和confirm_password 字段添加到我的UserSerializer。我编写了一个名为create 的函数来为我的password 字段创建哈希密码,但在它创建哈希密码之前,我希望它确保confirm_passwordpassword 匹配。如果我删除 confirm_password 字段,代码可以正常工作。有什么问题?

[更新]

我的序列化器.py

# serializer define the API representation
class UserSerializer(serializers.HyperlinkedModelSerializer):

    # password field
    password = serializers.CharField(
        write_only = True,
        required = True,
        help_text = 'Enter password',
        style = {'input_type': 'password'}
    )
    
    # confirm password field
    confirm_password = serializers.CharField(
        write_only = True,
        required = True,
        help_text = 'Enter confirm password',
        style = {'input_type': 'password'}
    )

    class Meta:
        model = User
        fields = [
            'url', 'first_name', 'last_name', 'email',
            'password', 'confirm_password', 'is_staff'
        ]
    
    def create(self, validated_data):
        if validated_data.get('password') != validated_data.get('confirm_password'):
            raise serializers.ValidationError("Those password don't match") 

        elif validated_data.get('password') == validated_data.get('confirm_password'):
            validated_data['password'] = make_password(
                validated_data.get('password')
            )

        return super(UserSerializer, self).create(validated_data)

我遇到的错误

TypeError: User() got an unexpected keyword argument 'confirm_password'

[20/Aug/2020 16:15:44] "POST /users/ HTTP/1.1" 500 168152

浏览器出错

TypeError at /users/
Got a `TypeError` when calling `User.objects.create()`. This may be because you have a writable field on the serializer class that is not a valid argument to `User.objects.create()`. You may need to make the field read-only, or override the UserSerializer.create() method to handle this correctly.

如果您需要更多详细信息,我可以编辑问题。太棒了!

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    您正在尝试将字段 confirm_password 保存到您的 User 模型中。我相信这个字段只是用来确认密码的,但是User模型真的没有这个字段。

    在保存之前尝试从validated_data弹出这个字段:

    def create(self, validated_data):
            if validated_data.get('password') != validated_data.get('confirm_password'):
                raise serializers.ValidationError("Those password don't match") 
    
            elif validated_data.get('password') == validated_data.get('confirm_password'):
                validated_data['password'] = make_password(
                    validated_data.get('password')
                )
    
            validated_data.pop('confirm_password'). # add this
            return super(UserSerializer, self).create(validated_data)
    

    附:验证通常在validate() 方法中完成,而不是在create() 中。

    【讨论】:

    • 当我添加那 1 行时,它给了我这个错误django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username
    • 这是另一个错误,因为使用此用户名的用户已经存在。可能您必须在序列化程序中为用户名添加唯一性。
    • 或者,如果 username 在您的 User 模型中是唯一的,则只需在 Meta.fields 中添加 username。也许这会有所帮助。创建有关它的新问题或至少添加您的User 模型。
    • 通过将username 添加到fields=[ ] 来工作!谢谢!
    【解决方案2】:

    from_the_docs.

    尝试分别使用password1password2 而不是passwordconfirm_passowrd 作为密码字段名称。

    【讨论】:

    • 尝试制作confirm_password字段read_only
    • @from_the_docs confirm_password 不是只读字段。 read_only 字段作为响应发送。
    【解决方案3】:

    您正在create 方法中执行验证。这不是正确的做法。这应该在序列化程序的is_validvalidate 方法中完成。你的create 方法应该是这样的

    def create(self, validated_data):
        # confirm_password should not be sent to create as it is not part of User model
        validated_data.pop('confirm_password', None)
        return super(UserSerializer, self).create(validated_data)
    

    【讨论】:

    • 当我添加那 1 行时,它给了我这个错误django.db.utils.IntegrityError: UNIQUE constraint failed: auth_user.username
    • 那是您的数据问题。您应该在验证方法中执行所有验证。 like 密码是否相同,此电子邮件的用户是否已存在等。当您调用 serializer.save() 时,将运行第一个验证。之后,代码将进入create方法。如果该邮箱的用户已经存在,则不会进入create方法。
    猜你喜欢
    • 2016-09-17
    • 2012-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    相关资源
    最近更新 更多