Reputation: 8951
I'm trying to use the built in Django password reset. Looking through the Django docs, from what I gather it basically involves just adding a few URL's to urls.py
urls.py
:
urlpatterns = [
url(r'^login/$', views.login_view, name='login'),
url(r'^password_reset/$', auth_views.password_reset, {'post_reset_redirect' : '/accounts/password_reset_done/'}, name='password_reset'),
url(r'^password_reset_done/$', auth_views.password_reset_done, name='password_reset_done'),
url(r'^password_reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', auth_views.password_reset_confirm, {'post_reset_redirect' : '/accounts/password_done/'}, name='password_reset_confirm'),
url(r'^password_done/$', auth_views.password_reset_complete, name='password_done'),
url(r'^auth/$', views.login_auth, name='login_auth'),
url(r'^register/$', views.register_user, name='register'),
url(r'^logout/$', views.logout_user, name='logout'),
]
login.html
:
{% extends "base.html" %}
{% block content %}
<title>{% block title %} | Login{% endblock %}</title>
<form action="/accounts/auth/" method="POST">
<h2>Login</h2>
{% if error_message %}<div class="formfielderrors">* {{ error_message }}</div>{% endif %}
{% csrf_token %}
<label for="username">Username: </label>
<br>
<input type="text" name="username" value="" id="username">
<br><br>
<label for="password">Password: </label>
<br>
<input type="password" name="password" value="" id="password">
<br><br>
<a href="/accounts/password_reset/">Forgot Password?</a>
<br><br>
<input type="submit" value="Login" class="greenButton">
</form>
{% endblock content %}
I'm fairly certain that I've properly added these URL's, and the r'^password_reset/$'
page loads properly, but after entering my email and clicking 'Reset my password', I get the following error:
NoReverseMatch at /accounts/password_reset/
I'm not totally sure what this error even means, so it's been pretty hard for me to debug. From looking through the documentation, this doesn't seem like difficult functionality to implement, but I can't seem to get it working. What am I doing wrong here?
The full error:
response = self.process_exception_by_middleware(e, request)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/contrib/auth/views.py", line 49, in inner
return func(*args, **kwargs)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/contrib/auth/views.py", line 205, in password_reset
form.save(**opts)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/contrib/auth/forms.py", line 259, in save
html_email_template_name=html_email_template_name)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/contrib/auth/forms.py", line 208, in send_mail
body = loader.render_to_string(email_template_name, context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/loader.py", line 97, in render_to_string
return template.render(context, request)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/backends/django.py", line 95, in render
return self.template.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 206, in render
return self._render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 197, in _render
return self.nodelist.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 988, in render
bit = node.render_annotated(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 955, in render_annotated
return self.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/defaulttags.py", line 41, in render
output = self.nodelist.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 988, in render
bit = node.render_annotated(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 955, in render_annotated
return self.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/loader_tags.py", line 60, in render
result = self.nodelist.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 988, in render
bit = node.render_annotated(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/base.py", line 955, in render_annotated
return self.render(context)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/defaulttags.py", line 513, in render
six.reraise(*exc_info)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/template/defaulttags.py", line 499, in render
url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/core/urlresolvers.py", line 600, in reverse
return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/Users/tomeldridge/Desktop/Misc/Hobbies/Programming/Projects/Pygamers/venv/lib/python2.7/site-packages/django/core/urlresolvers.py", line 508, in _reverse_with_prefix
(lookup_view_s, args, kwargs, len(patterns), patterns))
NoReverseMatch: Reverse for 'password_reset_confirm' with arguments '()' and keyword arguments '{u'uidb64': 'MQ', u'token': u'49h-b07b0dfeb4aa82d09149'}' not found. 0 pattern(s) tried: []
[17/Feb/2016 01:47:33] "POST /accounts/password_reset/ HTTP/1.1" 500 173812
Upvotes: 5
Views: 2067
Reputation: 13058
The problem comes from your use of namespace for account urls and Django's built-in template used in the view. In the template registration/password_reset_email.html
you'll see:
{% url 'password_reset_confirm' uidb64=uid token=token %}
However, the url name password_reset_confirm
doesn't exist in your app because you used the namespace "accounts" - the url became accounts:password_reset_confirm
instead.
You might consider creating a separate file to store urls that don't use the "accounts" namespace. E.g.
# urls_django_auth.py
url_patterns = [
url(r'^password_reset/$', auth_views.password_reset, ...),
url(r'^password_reset_done/$', auth_views.password_reset_done, ...),
... other django auth views ...
]
# urls.py
url_patterns = [
....
url(r'^accounts/', include('accounts.urls', namespace='accounts')),
url(r'^accounts/', include('accounts.urls_django_auth')),
]
Or you can create your own version of password_reset_email.html
with the correct URL pattern, and pass it to your view
url(r'^password_reset/$', auth_views.password_reset, {
'post_reset_redirect' : '/accounts/password_reset_done/',
'email_template_name': '/your/own/password_reset_email.html'
}, name='password_reset')
Upvotes: 6