Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - NoReverseMatch at /accounts/password_reset/

Tags:

python

django

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
like image 542
123 Avatar asked Feb 17 '16 00:02

123


1 Answers

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')
like image 185
Derek Kwok Avatar answered Sep 21 '22 20:09

Derek Kwok