Question

I want to keep a clean urls description in my projet, so I use namespaces:

project/urls.py:

urlpatterns = patterns('',
url(r'^contracts/', include('apps.contracts.urls', namespace='contracts')),
url(r'^accounts/', include('apps.registration_custom.backends.vince.urls', namespace='accounts')),

registration_custom/backends/vince/urls.py:

urlpatterns = patterns('',
                   url(r'^activate/complete/$',
                       TemplateView.as_view(template_name='registration/activation_complete.html'),
                       name='registration_activation_complete'),
                   # Activation keys get matched by \w+ instead of the more specific
                   # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
                   # that way it can return a sensible "invalid key" message instead of a
                   # confusing 404.
                   url(r'^activate/(?P<activation_key>\w+)/$',
                       ActivationView.as_view(),
                       name='registration_activate'),
                   url(r'^register/$',
                       CustomRegistrationView.as_view(),
                       name='registration_register'),
                   url(r'^register/complete/$',
                       TemplateView.as_view(template_name='registration/registration_complete.html'),
                       name='registration_complete'),
                   url(r'^register/closed/$',
                       TemplateView.as_view(template_name='registration/registration_closed.html'),
                       name='registration_disallowed'),
                   (r'', include('registration.auth_urls')),
                   )

With this configuration, if I request /accounts/password/reset/ I get an error:

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

But if I'm not namespacing my urls, everything goes clean with my /accounts/password/reset/ request.

What I understand is that the django/contrib/auth/views/password_reset view is using reverse() on 'django.contrib.auth.views.password_reset_done'. And the urls dispatcher get lost because it should be asking for 'accounts:auth_password_reset_done'.

Am I guessing right?

Then what would be my options?

EDIT. The template code that redirect to /accounts/password/reset :

{% extends "base.html" %}
{% load i18n %}

{% block content %}
<form method="post" action="">
  {% csrf_token %} 
  {{ form.as_p }}

  <input type="submit" value="{% trans 'Log in' %}" />
  <input type="hidden" name="next" value="{{ next }}" />
</form>

<p>{% trans "Forgot password" %}? <a href="{% url 'accounts:auth_password_reset' %}">{% trans "Reset it" %}</a>!</p>
<p>{% trans "Not member" %}? <a href="{% url 'accounts:registration_register' %}">{% trans "Register" %}</a>!</p>
{% endblock %}
Was it helpful?

Solution

Wahaha, I've made a step in my Django's comprehension!

In fact, Django auth module is looking for a view when he asks for: reverse('django.contrib.auth.views.password_reset_done')

But my urls config is namespaces, so Django is lost (here I don't know exactly, maybe someone can explain better).

So I need to say to Django to look first for a non-namespaced url pattern first, just for it's core code.

So my trick is to add a line in the myproject/urls.py:

urlpatterns = patterns('',
url(r'^contracts/', include('apps.contracts.urls', namespace='contracts')),

# this is tricky
# the default auth module need to reverse some urls like reverse('django.contrib.auth.views.password_reset_done')
# but I want to keep a namespaced urls config
# then I need to supply a first url path to django when he look at non-namespaced urls
url(r'^accounts/', include('registration.auth_urls')),
url(r'^accounts/', include('apps.registration_custom.backends.vince.urls', namespace='accounts')),

And everything is working fine!

I admit that this is not an elegant solution, but it has the benefit to keep my namespaces right, so will be the templates.

OTHER TIPS

Add correct namespace and app name for include('registration.auth_urls') (see last line)

urlpatterns = patterns('',
                   url(r'^activate/complete/$',
                       TemplateView.as_view(template_name='registration/activation_complete.html'),
                       name='registration_activation_complete'),
                   # Activation keys get matched by \w+ instead of the more specific
                   # [a-fA-F0-9]{40} because a bad activation key should still get to the view;
                   # that way it can return a sensible "invalid key" message instead of a
                   # confusing 404.
                   url(r'^activate/(?P<activation_key>\w+)/$',
                       ActivationView.as_view(),
                       name='registration_activate'),
                   url(r'^register/$',
                       CustomRegistrationView.as_view(),
                       name='registration_register'),
                   url(r'^register/complete/$',
                       TemplateView.as_view(template_name='registration/registration_complete.html'),
                       name='registration_complete'),
                   url(r'^register/closed/$',
                       TemplateView.as_view(template_name='registration/registration_closed.html'),
                       name='registration_disallowed'),
                   (r'', include('registration.auth_urls'), namespace='accounts', app_name='registration'),
                   )
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top