Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reverse for 'password_change_done' with arguments '()' and keyword arguments '{}' not found

Background

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 %}

The Problem

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: []

What I tried

I have no idea, why this should be happening.

  1. I tried removing the single quotes from url 'userauth_password_change'
  2. I made sure the password-change-donepage exists in urls.py and is available
  3. I read the solutions at Reverse for '*' with arguments '()' and keyword arguments '{}' not found, Django: Reverse for 'detail' with arguments '('',)' and keyword arguments '{}' not found, Django change_password NoReverseMatch at /accounts/password/change/ (and a few more, I tried all the solutions there, but I can't find a problem in my own code)

Any help is appreciated. Thank you!

like image 675
Rias Avatar asked Jun 13 '15 17:06

Rias


3 Answers

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.

like image 190
Jim Bob Avatar answered Oct 20 '22 17:10

Jim Bob


In some section you call the url named "password_change_done"

the correct name is: "userauth_password_change_done"

like image 3
alexander Avatar answered Oct 20 '22 15:10

alexander


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.

like image 3
Rias Avatar answered Oct 20 '22 17:10

Rias