I'm trying to write a serializer (in Django REST Framework) to update a user's account details. Here is the update() method:
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)
When I perform a PATCH request to the view with "password", "confirm_password" and "old_password" as fields, it appears to have worked. Then when I try to log into the account again, it fails (using both old and new passwords). When I check the admin settings and view the user I am trying to edit, I get the following:
Invalid password format or unknown hashing algorithm.
Raw passwords are not stored, so there is no way to see this user's password, but you can change the password using this form.
I believe User.set_password() is supposed to handle hashing/etc. automatically, so why do I get this error?
You deleted password
from self.validated_data
but not from validated_data
dict which passed to superclass's update
method. Try this:
validated_data.pop("password") # remove self, just leave validated_data
return super(UserInfoSerializer, self).update(instance, validated_data)