I am having an issue with Django users changing passwords - I have built a few production sites in Django, just none in about a year (or in 1.8), but I don't recall having this issue before.
Summary
When a user changes their password, the user is logged out, but the password is successfully changed.
Details
I have a view that allows a user to change a password, I am using standard django forms and the auth framework, and to stress: changing the password works, it just logs the user out so that they have to login again.
I actually don't mind this terribly, I would prefer that the user be redirected to their dashboard with a message update, if i need to reauth the user in the code, then I will, just seems kind of clunky.
here is my view function:
@login_required def user_change_password(request): """Allows a user to change their password""" if request.method == "POST": form = SubscriberPasswordForm(request.POST) if form.is_valid(): try: request.user.set_password(form.cleaned_data['password']) request.user.save() except Exception, err: print "Error changing password: {}".format(err) messages.add_message(request, messages.ERROR, 'The password could not be changed, please try again ' 'later. This admins have been notified of this error.') else: #this outputs True print request.user.is_authenticated() messages.add_message(request, messages.INFO, 'Your password has been changed successfully') return HttpResponseRedirect("/accounts/dashboard/") else: form = SubscriberPasswordForm() return render(request, "accounts/change-password.html", {"form": form})
So the password is changed, the user gets redirected to the dashboard page, the @login_required decorator then redirects them back to the login screen.
The password form is here, though it is pretty straightforward.
class SubscriberPasswordForm(forms.Form): password = forms.CharField(widget=forms.PasswordInput) cpassword = forms.CharField(widget=forms.PasswordInput) def clean_cpassword(self): password1 = self.cleaned_data.get("password") password2 = self.cleaned_data.get("cpassword") if password1 and password2 and password1 != password2: raise forms.ValidationError( self.error_messages['password_mismatch'], code='password_mismatch', )
from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid ...
Programmatically, you can create / save a new User without a password argument, and it will not raise any exceptions. In fact, you can even create a user without any arguments.
For django 1.9:
from django.contrib.auth import update_session_auth_hash def password_change(request): if request.method == 'POST': form = PasswordChangeForm(user=request.user, data=request.POST) if form.is_valid(): form.save() update_session_auth_hash(request, form.user)
The following fields must be supplied in the POST request:
See detailed docs at update_session_auth_hash
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With