4
votes

When changing a password via django-allauth, the default redirect after successfully posting the password change is again the password change template. Since I find this confusing, I overrode the original PasswordChnageView in my views.py file:

from allauth.account.views import PasswordChangeView
from django.urls import reverse_lazy

class MyPasswordChangeView(PasswordChangeView):
    success_url = reverse_lazy('home')

and changed my urls.py file:

from django.urls import path, include
from users.views import MyPasswordChangeView 

urlpatterns = [
        ...
        # User management
        path('accounts/password/change/', MyPasswordChangeView.as_view(), name="account_change_password"),
        path('accounts/', include('allauth.urls')),
        ...
    ]

This works fine when the user is logged in, however when I try to access the url http://127.0.0.1:8000/accounts/password/change/ while being logged out, I get the following error message: AttributeError at /accounts/password/change/ 'AnonymousUser' object has no attribute 'has_usable_password' Before I created my custom override, the result of the same behaviour was that I was redirected to the login url http://127.0.0.1:8000/accounts/login/?next=/

What do I need to change with my custom view, to redirect to the login url when a logged out user tries to acces the url http://127.0.0.1:8000/accounts/password/change/

1
Did you forgot to add permission on password change view? I don't thing anonymous users can change the password. This should result in access denied error.Charnel
IMO this should be taken care of by the original django-allauth PasswordChangeView, the only thing I am overriding is success_url, so there shouldn't be anything else changingDaniel
The PasswordChangeView from allauth doesn't have the login required decorator in itself, that's added directly in the urls: the view used is password_change = login_required(PasswordChangeView.as_view())dirkgroten

1 Answers

2
votes

Look at the source code: The PasswordChangeView from allauth doesn't have the login required decorator in itself, that's added directly in the urls: the view used is password_change = login_required(PasswordChangeView.as_view()).

There are 2 ways:

  1. Add login_required decorator to your URL.
from django.contrib.auth.decorators import login_required
        path('accounts/password/change/', login_required(MyPasswordChangeView.as_view()), name="account_change_password"),
  1. Inherit from LoginRequiredMixin.
from django.contrib.auth.mixins import LoginRequiredMixin

class MyPasswordChangeView(LoginRequiredMixin, PasswordChangeView):
    success_url = reverse_lazy('home')

Make sure that LoginRequiredMixin is to the left most side of your child class.