Apologies, I’m new to Django, so this might be super obvious.
I’m trying to test the user change-password functionality on my webapp.
I can see that the password has successfully changed when I login as admin and look at the relevant user-id (the redacted salt
and hash
values both change). However, I’m unable to login with the new user credentials (username and password mismatch). The password encryption algorithm hasn’t changed (pbkdf2_sha256) - so I’m not sure where it’s going wrong.
Below is a snippet of the relevant part of the code:
uid = force_str(urlsafe_base64_decode(uidb64))
user = MyUser.objects.get(pk=uid)
# ...
form = SetPasswordForm(user,request.POST)
if form.is_valid():
user = form.save(commit=False)
print('user = ' + str(user))
print(form.cleaned_data.get("new_password1"))
user.save()
The print statements above show exactly what I was expecting (i.e. the test username and the new password are printed).
Is this something to do with me creating a new user model MyUser
rather than the Django out of the box? Since SetPasswordForm
takes user
as an argument, I assumed all would be well.
Any help greatly appreciated. Also, if anyone knows of any solid examples I could look at of the Django authentication used in practice, I’d love to take a look. The docs are a bit dry in this area.
cheers,
Paul
You can use user.set_password(password)
in order to set password received from form data and then user.save()
to save the instance.
To add to @addwebsolution’s answer above, the best examples of Django authentication in practice would be to look at Django’s own authentication views in django.contrib.auth.views
, along with the forms in django.contrib.auth.forms
.
2 Likes
Thanks for that @addwebsolution and @KenWhitesell. I’ll have a go doing set_password
explicitly.
But - how is that different to what SetPasswordForm
is doing? According to the source code it’s just doing set_password
anyway. Am I missing something?
def save(self, commit=True):
self.user.set_password(self.cleaned_data['new_password1'])
if commit:
self.user.save()
return self.user
Side note: the line:
is creating an instance of the SetPasswordForm
object. It’s not, of its own, doing anything with the data other than populating the object with what was submitted from the browser.
It’s the line:
that should be causing the save
method to update the password.
Now, the key point that I missed was:
By this, you’re trying to use a custom user model?
If so, did you make the settings change to AUTH_USER_MODEL?
Are you using a customized login view/form?
Yes, I knew that much
Yes - the Django tutorial I was following suggested that it’s always good practice to create your own user model (but didn’t really explain why).
I have set AUTH_USER_MODEL
in settings.py.
To be clear - I can create new users and login fine via this same user model, it’s only when I try to save a new password that it falls over. This is why I was scratching my head.
Ah, I’m an idiot.
I re-ran migrations and now everything is working as expected. Works via form.save
and via user.set_password
.
Apologies - I mist have made some changes to the user model without migrating everything.
1 Like
No worries - we’ve all been there.
1 Like
Thanks for the super-fast advice!