Search code examples
djangodjango-rest-frameworkdjango-allauth

Django REST auth: error rendering django-allauth template after email confirmation


I'm using a Django REST Framework API to communicate from my AngularJS frontend to the Django backend, which is working really well. I installed the super helpful django-rest-auth package as well as their optional registration add on. Authentication works, and registration mostly works as well.

My problem is that the confirmation link in the confirmation email sent to the new user gives me a NoReverseMatch error. Thanks to the django-rest-auth FAQ, I know the confirmation doesn't work by default and requires overriding but I mirrored what the poster of this question did. My urls:

from allauth.account.views import confirm_email as allauthemailconfirmation
...
url(r'^rest-auth/', include('rest_auth.urls')),
url(r'^rest-auth/registration/account-confirm-email/(?P<key>\w+)/$', allauthemailconfirmation, name="account_confirm_email"),
url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
...

And the exact error:

NoReverseMatch at /rest-auth/registration/account-confirm-email/ahhuvpetqmcsd6hjlgrjuru11mwfkpk9sljmfbuprxwz8elnajabr84vusnmdw7r/
Reverse for 'account_email' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []

The poster of this question seems to have had the same issue, though I don't understand how the one answer applies, and it's not accepted, so I'm not sure if it even works.

EDIT:

Based on the first comment below, I tried changing the URL name to account_email. This still resulted in an error, but after re-reading the error, I realized it's thrown during render of a default django-allauth template, after the allauth view has handled the confirmation:

Error during template rendering

In template C:\Python34\lib\site-packages\allauth\templates\base.html, error at line 26
Reverse for 'account_email' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
    16      <li>{{message}}</li>
17      {% endfor %}
18        </ul>
19      </div>
20      {% endif %}
21  
22      <div>
23        <strong>Menu:</strong>
24        <ul>
25      {% if user.is_authenticated %}
26  
        <li><a href="
      {% url 'account_email' %}
      ">Change E-mail</a></li>


27      <li><a href="{% url 'account_logout' %}">Sign Out</a></li>
28      {% else %}
29      <li><a href="{% url 'account_login' %}">Sign In</a></li>
30      <li><a href="{% url 'account_signup' %}">Sign Up</a></li>
31      {% endif %}
32        </ul>
33      </div>
34      {% block content %}
35      {% endblock %}
36      {% endblock %}

So I think the code I used from the linked github issue is correct for the confirmation email, and this error happens during render of the template after the allauth view confirms the email address. I would expect the URLs in lines 26-30 above to be part of the include('rest_auth.registration.urls') set, since the django-rest-auth registration option uses django-allauth.

I'm not sure what I'd need to do to get this URL working if the allauth view is handling the confirmation correctly. I could be wrong about that guess, though.

EDIT 2 I took the advice from a comment below and printed off all the URLs:

>>> show_urls(urls.urlpatterns)
^api/
   ^$
   ^\.(?P<format>[a-z0-9]+)/?$

   ....autogenerated viewset URLs....

 ^api-browse/
   ^login/$
   ^logout/$
 ^rest-auth/
   ^password/reset/$
   ^password/reset/confirm/$
   ^login/$
   ^logout/$
   ^user/$
   ^password/change/$
 ^rest-auth/registration/account-confirm-email/(?P<key>[-:\w]+)/$
 ^rest-auth/registration/
   ^$
   ^verify-email/$
   ^account-confirm-email/(?P<key>\w+)/$
 ^$

 ....explicitly added URLs for custom viewset methods...

 ^register/$
 ^login/$
 ^logout$
 ^admin/

   ....admin URLs....

The NoReverseMatch error makes sense now, since the URL patterns on the allauth confirm email view simply aren't present.

I noticed in the linked StackOverflow question that the poster had included the allauth urls as so:

url(r'^accounts/', include('allauth.urls')),

When I added this line, it worked!


Solution

  • To recap the final edit above, the issue here was that I was attempting to use the django-allauth default email confirmation template, but hadn't included the allauth urls explicitly.

    I didn't think that step was required since django-rest-framework's registration option uses allauth, but since the account_confirm_email view must be overridden anyway, the authors of that package seem to expect users to POST the key to /verify_email/.

    To make use of the allauth email confirmation template, include the following in urls.py:

    url(r'^accounts/', include('allauth.urls')),