문제

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 %}
도움이 되었습니까?

해결책

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.

다른 팁

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'),
                   )
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top