Django 2.0 – Reverse for 'password_change_done' not found. 'password_change_done' is not a valid view function or pattern name

Question:

I’m having this error message after trying to change my app’s password.

Do you have any idea of what’s causing this route to fail?

Actually, it is changing the password but it isn’t rendering the success template “password_change_done.html”.

Thanks!

app/urls.py

from django.contrib.auth import views as auth_views
from django.urls import path
​
from . import views
​
app_name = 'account'
​
urlpatterns = [
    # path('login/', views.user_login, name='login'),
    path('', views.dashboard, name='dashboard'),
​
    # login / logout urls
    path('login/', auth_views.LoginView.as_view(template_name='registration/login.html'), name='login'),
    path('logout/', auth_views.LogoutView.as_view(), name='logout'),
    path('logout-then-login/', auth_views.logout_then_login, name='logout_then_login'),
​
    # change password urls
    path('password-change/', auth_views.PasswordChangeView.as_view(), name='password_change'),
    path('password_change/done/', auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]
​

​

ERROR MESSAGE

# NoReverseMatch at /account/password-change/
# Reverse for 'password_change_done' not found. 'password_change_done' is not a valid view function or pattern name.
# Request Method:   POST
# Request URL:  http://localhost:8000/account/password-change/
# Django Version:   2.0.4
# Exception Type:   NoReverseMatch
# Exception Value:  
# Reverse for 'password_change_done' not found. 'password_change_done' is not a valid view function or pattern name.
# Exception Location:   C:envdjango_social_websitelibsite-packagesdjangourlsresolvers.py in _reverse_with_prefix, line 632
# Python Executable:    C:envdjango_social_websiteScriptspython.exe
# Python Version:   3.6.3
# Python Path:  
# ['C:\Projects\django_social_website',
#  'C:\env\django_social_website\Scripts\python36.zip',
#  'C:\ProgramData\Anaconda3\DLLs',
#  'C:\ProgramData\Anaconda3\lib',
#  'C:\ProgramData\Anaconda3',
#  'C:\env\django_social_website',
#  'C:\env\django_social_website\lib\site-packages',
#  'C:\env\django_social_website\lib\site-packages\setuptools-28.8.0-py3.6.egg',
#  'C:\env\django_social_website\lib\site-packages\pip-9.0.1-py3.6.egg']
# Server time:  Thu, 5 Apr 2018 21:34:22 +0000

​

app/templates/registration/password_change_form.html

{% extends "base.html" %}
​
{% block title %}Change your password{% endblock %}
​
{% block content %}
    <h1>Change your password</h1>
    <p>Use the form below to change your password.</p>
    <form action="." method="post">
        {{ form.as_p }}
        {% csrf_token %}
        <p><input type="submit" value="Change"></p>
    </form>
{% endblock %}
​

​

app/templates/registration/password_change_done.html

{% extends "base.html" %}
​
{% block title %}Password changed{% endblock %}
​
{% block content %}
    <h1>Password changed</h1>
    <p>Your password has been successfully changed.</p>
{% endblock %}

Thanks for your help!

Asked By: ralfillo

||

Answers:

I think the problem here is, as Tobit hints, is that your URLs are using an application namespace called account. That has been defined by the presence of app_name = 'account' in your urls.py.

The PasswordChangeView does not expect a namespace when looking up the password_change_done view. However, you can override that in your urls.py by specifying an explicit success_url attribute:

from django.urls import reverse_lazy
​
# change password urls
path('password-change/', auth_views.PasswordChangeView.as_view(success_url=reverse_lazy('account:password_change_done')), name='password_change'),

More info on namespaces: https://docs.djangoproject.com/en/2.0/topics/http/urls/#url-namespaces-and-included-urlconfs

Answered By: Will Keeling

It works for me:

# account urls.py

from django.urls import path, include
from django.contrib.auth import views as auth_views    
from . import views
from django.urls import reverse_lazy

app_name = 'account'

urlpatterns = [    
    #Password Changes URLs
    path('password_change/', auth_views.PasswordChangeView.as_view(
        success_url=reverse_lazy('account:password_change_done')
    ), name='password_change'),
    path('password_change/done/',auth_views.PasswordChangeDoneView.as_view(), name='password_change_done'),
]

The main link is here:
https://django.fun/en/qa/11928/

Answered By: Angel Josue