【问题标题】:Namespacing urls in django-registrationdjango-registration 中的命名空间 url
【发布时间】:2025-11-26 16:05:02
【问题描述】:

我想在我的项目中保留一个干净的 urls 描述,所以我使用命名空间:

项目/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')),
                   )

使用此配置,如果我请求 /accounts/password/reset/ 我收到错误:

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

但是,如果我没有为我的网址命名空间,那么我的 /accounts/password/reset/ 请求一切都会变得干净。

我的理解是 django/contrib/auth/views/password_reset 视图在 'django.contrib.auth.views.password_reset_done' 上使用 reverse()。并且 urls 调度程序迷路了,因为它应该要求 'accounts:auth_password_reset_done'。

我猜对了吗?

那么我的选择是什么?

编辑。 重定向到 /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 %}

【问题讨论】:

  • 你能显示你的模板代码重定向到/account/password/reset/吗?
  • @sachitad 是的,我编辑我的帖子

标签: django python-2.7 django-authentication django-registration


【解决方案1】:

include('registration.auth_urls') 添加正确的命名空间和应用名称(见最后一行)

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'),
                   )

【讨论】:

    【解决方案2】:

    哇哈哈,我对 Django 的理解又进了一步!

    其实django的auth模块在他请求的时候是在找视图:reverse('django.contrib.auth.views.password_reset_done')

    但是我的 urls 配置是命名空间,所以 Django 丢失了(这里我不太清楚,也许有人可以解释得更好)。

    所以我需要告诉 Django 首先寻找一个非命名空间的 url 模式,只是为了它的核心代码。

    所以我的诀窍是在 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')),
    

    一切正常!

    我承认这不是一个优雅的解决方案,但它有利于保持我的命名空间正确,模板也是如此。

    【讨论】: