7

I have set the following entry in the urls.py

(r'^password_reset/$', 'django.contrib.auth.views.password_reset'),

but once I go to http://127.0.0.1:8000/password_reset/ I get the error message:

NoReverseMatch at /password_reset/
Reverse for 'django.contrib.auth.views.password_reset_done' with arguments '()' and keyword arguments '{}' not found.

I was expecting password_reset_done view also to be coming out of the box. So what am I supposed to do at this stage?

UPDATE

After trying Blair's solution, I got a step closer.

(r'^password_reset_done/$', 'django.contrib.auth.views.password_reset_done'),

According to the book 'Django 1.0 Website Development', these built-in views should be used out of the box without further hassle. But maybe it has changed since Django 1.0... Would be great if someone could shed light on this. Thanks

Houman
  • 64,245
  • 87
  • 278
  • 460

3 Answers3

3

I have finally found the solution. I think there is always the slight misunderstanding between MVC and MTV pattern. In MTV (Django) the View stands for the controller and the Template stands for the View.

Hence while its true that the change password "Views" are coming built-in out-of-the-box, the actual templates (look & feel) still needs to be generated by the user while the underlying form (widget) is generated by Django automatically. It gets more clear when looking at the code.

Therefore add these two lines to url.py

(r'^change-password/$', 'django.contrib.auth.views.password_change'), 
(r'^password-changed/$', 'django.contrib.auth.views.password_change_done'),

Then Under myproject/templates/registration add these two files

password_change_done.html

{% extends "base.html" %}
{% block title %}Password Change Successful{% endblock %}
{% block head %}Password Change Completed Successfully{% endblock %}
{% block content %}
    Your password has been changed successfully. Please re-login with your new credentials 
    <a href="/login/">login</a> or go back to the
    <a href="/">main page</a>.
{% endblock %}

password_change_form.html

{% extends "base.html" %}
{% block title %}Change Registration{% endblock %}
{% block head %}Change Registration{% endblock %}
{% block content %}
    <form method="post" action=".">
        {{form.as_p}}
        <input type="submit" value="Change" />
        {% csrf_token %}
    </form>
{% endblock %}

enter image description here

Houman
  • 64,245
  • 87
  • 278
  • 460
2

Django needs to know which URL to redirect the user to once they have completed the form on the password_reset page. So add another line to your URL configuration:

(r'^password_reset_done/$', 'django.contrib.auth.views.password_reset_done'),
Blair
  • 15,356
  • 7
  • 46
  • 56
  • I have done what you suggested, now it says: TemplateDoesNotExist at /password_reset/ ... Exception Value: registration/password_reset_form.html it doesnt make much sense to me, if I had to create the template myself. Am I missing here something? – Houman May 12 '12 at 22:50
  • Not entirely sure, I've always created custom templates so they fit in with the theme of the rest of the site. Having said that, there appears to be some matching templates in the django.contrib.admin app, so if you have the Django admin enabled they might be used? – Blair May 13 '12 at 01:27
1

As of django 1.11 password_change view is deprecated.

Deprecated since version 1.11: The password_change function-based view should be replaced by the class-based PasswordChangeView.

What worked for me was:

In urls.py

from django.contrib.auth import views as auth_views
...
url('^account/change-password/$',
    auth_views.PasswordChangeView.as_view(
        template_name='registration/passwd_change_form.html'),
    name='password_change'),
url(r'^account/password-change-done/$',
    auth_views.PasswordChangeDoneView.as_view(
        template_name='registration/passwd_change_done.html'),
    name='password_change_done'),

And then add the couple of templates passwd_change_form.html and passwd_change_done.html under registration.

Note that I'm not using the default name, for some reason when I did that it defaulted to the django admin views.

Iker
  • 73
  • 1
  • 8
  • Thanks for mentionning the warning. Also this is the case for `password_reset` it's replaced by `PasswordResetView` and i'll will work. – Chiheb Nexus Oct 08 '18 at 03:45