我正在尝试编写一个序列化程序(在Django REST Framework中)以更新用户的帐户详细信息。这是update()方法:
def update(self, instance, validated_data):
...
if all([item in self.validated_data for item in ["password", "confirm_password", "old_password"]]):
user = authenticate(username=self.context["request"].user.username, password=self.validated_data["old_password"])
if user is not None:
if self.validated_data["password"] == self.validated_data["confirm_password"]:
validate_password(self.validated_data["password"])
user.set_password(self.validated_data["password"])
user.save()
else:
raise serializers.ValidationError({"confirm_password": "Passwords do not match"})
else:
raise serializers.ValidationError({"old_password": "Password incorrect"})
self.validated_data.pop("password")
return super(UserInfoSerializer, self).update(instance, validated_data)
当我使用“密码”,“ confirm_password”和“ old_password”作为字段对视图执行PATCH请求时,它似乎起作用了。然后,当我尝试再次登录该帐户时,它将失败(使用旧密码和新密码)。当我检查管理员设置并查看我要编辑的用户时,得到以下信息:
无效的密码格式或未知的哈希算法。
原始密码未存储,因此无法查看此用户的密码 密码,但是您可以使用此表单更改密码。
我相信User.set_password()应该可以处理哈希/等。自动,为什么我会出现此错误?
答案 0 :(得分:2)
您从password
中删除了self.validated_data
,但没有从传递给超类的validated_data
方法的update
字典中删除。试试这个:
validated_data.pop("password") # remove self, just leave validated_data
return super(UserInfoSerializer, self).update(instance, validated_data)
答案 1 :(得分:1)
万一有兴趣使用我的代码,这是最终的工作代码:
def update(self, instance, validated_data):
...
if all([item in validated_data for item in ["password", "confirm_password", "old_password"]]):
user = authenticate(username=instance.username, password=validated_data["old_password"])
if user is not None and user == instance:
if validated_data["password"] == validated_data["confirm_password"]:
validate_password(validated_data["password"])
instance.set_password(validated_data["password"])
instance.save() # change the password on the current instance object, otherwise changes will be overwritten
login(self.context["request"], instance) # without this line, the user is auto-logged out upon changing their password
else:
raise serializers.ValidationError({"confirm_password": "Passwords do not match"})
else:
raise serializers.ValidationError({"old_password": "Password incorrect"})
if "password" in validated_data:
validated_data.pop("password")
return super(UserInfoSerializer, self).update(instance, validated_data)