Reputation: 1996
I am trying to customize the authentication views in a Django project, but I can't seem to get the customized password_change view to run. I use Django 1.8.2 and Python 2.7.
The urls.py
of my module userauth
looks like the following:
from django.conf.urls import patterns, include, url
urlpatterns = patterns('django.contrib.auth.views',
url(r'^login/$', 'login', {'template_name': 'userauth/login.html'},
name='userauth_login'),
url(r'^logout/$', 'logout', {'next_page': '/'},
name='userauth_logout'),
url(r'^password-change/$', 'password_change',
{'template_name': 'userauth/password_change_form.html'},
name='userauth_password_change'),
url(r'^password-change-done/$', 'password_change_done',
{'template_name': 'userauth/password_change_done.html'},
name='userauth_password_change_done'),
)
this is referenced in the main urls.py
as this:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^account/', include('userauth.urls')),
]
The template of my userauth/password_change_form.html
{% extends "base.html" %}
{% block title %}{{ block.super }} - Change Password{% endblock %}
{% block toggle_login %}{% endblock %}
{% block content %}
<form action="{% url 'userauth_password_change' %}" method="post" accept-charset="utf-8">
{{ form.as_p }}
{% csrf_token %}
<input type="submit" value="Change password"/>
</form>
{% endblock %}
And the template for userauth/password_change_done.html
{% extends "base.html" %}
{% block title %}{{ block.super }} - Password change successful{% endblock %}
{% block content %}
<p>Your password has been changed successfully.</p>
<a href="{% url 'products_product_index' %}">Back to your Account</a>
{% endblock %}
When I open the 'password_change_done'
page (at /account/password-change-done), then everything is fine.
But at 'password-change'
(/accunt/password-change) I am getting this error:
NoReverseMatch at /account/password-change/
Reverse for 'password_change_done' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
I have no idea, why this should be happening.
url 'userauth_password_change'
password-change-done
page exists in urls.py and is availableAny help is appreciated. Thank you!
Upvotes: 5
Views: 5517
Reputation: 631
in case if you are using
app_name
and trying to overwrite default template for update/change password you have to tell that Django:
from django.urls import path, reverse_lazy
from django.contrib.auth import views as auth_view
from . import views
app_name = 'account'
urlpatterns = [
path('login/', auth_view.LoginView.as_view(), name='login'),
path('logout/', auth_view.LogoutView.as_view(), name='logout'),
path('password_change/',
auth_view.PasswordChangeView.as_view(
template_name='registration/password_change_form.html',
success_url=reverse_lazy('account:password_change_done')), name='password_change'),
path('password_change/done/',
auth_view.PasswordChangeDoneView.as_view(
template_name='registration/password_change_done.html'), name='password_change_done'),
]
Upvotes: 0
Reputation: 101
I meet the same kind of problem. The reason is the "password_change_done" is hard code in the auth.views, so I extense the class base on the auth.views.PasswordChangeView。
the auth.views.PasswordChangeView:
class PasswordChangeView(PasswordContextMixin, FormView):
......
success_url = reverse_lazy('password_change_done')
the MyPasswordChangeView:
class MyPasswordChangeView(PasswordChangeView):
success_url = reverse_lazy('app_label:password_change_done')
just overide the success_url
.
and use MyPasswordChangeView in the urlpattern. Now, everything is ok.
Upvotes: 0
Reputation: 11
You need delete single quotes around the view name
{% url password_change_done %}
instead of
{% url 'password_change_done' %}
Upvotes: 1
Reputation: 459
Ok, so the suggested solution for me didn't work here. I'm using Django 1.8.8 in an application with a specific app label, so I need to specify a url in a template like this e.g. app_label:url_name. This meant the reverse for password_change_done would never work since it's app_label:password_change_done.
But thankfully there's a solution: 'post_change_redirect'. Hence I specified password_change like this:
url(r'^password_change$', 'django.contrib.auth.views.password_change', {'template_name': 'password_change.html', 'post_change_redirect': 'app_label:password_change_done'}, name='password_change'),
I'm sure others could use this to overcome the problem above and still keep their own custom url name.
Upvotes: 5
Reputation: 1996
The solution was, that the in the urls.py the name of the password_change_done link must be 'password_change_done'
:
url(r'^password-change-done/$', 'password_change_done',
{'template_name': 'userauth/password_change_done.html'},
name='password_change_done'),
I had a look into django.contrib.auth.views.password_change
(which was creating the problem) and realized, that the the url 'password_change_done'
is hardcoded there in Django 1.8.2.
Upvotes: 3
Reputation: 521
In some section you call the url named "password_change_done"
the correct name is: "userauth_password_change_done"
Upvotes: 3