我正在研究 Django 文档,但遇到了一个我无法理解的部分:what is an real example of how to use a namespace in an real question。我知道语法,但我不知道这样做的目的。
3 回答
通常,它们用于将每个应用程序的 URL 放入它们自己的命名空间中。这可以防止reverse()
Django 函数和{% url %}
模板函数返回错误的 URL,因为 URL 模式名称恰好在另一个应用程序中匹配。
我在项目级urls.py
文件中的内容如下:
from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', 'main.views.main', name='main'),
url(r'^login$', 'django.contrib.auth.views.login', name="login"),
url(r'^logout$', 'django.contrib.auth.views.logout',
{"next_page": "/"}, name="logout"),
# Admin
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
)
# Auto-add the applications.
for app in settings.LOCAL_APPS:
urlpatterns += patterns('',
url(r'^{0}/'.format(app), include(app + '.urls', namespace=app)),
)
请注意最后一部分:这将遍历我已安装的应用程序(settings.LOCAL_APPS
这是我添加的仅包含我的应用程序的设置;它被添加到INSTALLED_APPS
其中有其他东西,如 South),urls.py
在每个应用程序中查找 a,并将这些 URL 导入以应用程序命名的命名空间,并将这些 URL 放入以应用程序命名的 URL 子目录中。
因此,例如,如果我有一个名为 的应用程序hosts
,它hosts/urls.py
看起来像:
from django.conf.urls.defaults import *
urlpatterns = patterns('hosts.views',
url(r'^$', 'show_hosts', name='list'),
)
现在我views.py
可以调用reverse("hosts:list")
来获取调用页面的 URL hosts.views.show_hosts
,它看起来像"/hosts/"
. {% url "hosts:list" %}
在模板中也是如此。这样我就不必担心在另一个应用程序中与名为“list”的 URL 发生冲突,也不必在每个名称前加上hosts_
.
请注意,登录页面位于,{% url "login" %}
因为它没有被赋予命名空间。
考虑您正在使用如下 url 模式
url(r'^login/',include('app_name', name='login'))
还考虑您正在使用第三方应用程序,如 Django-RestFramework。当您使用该应用程序时,您必须在项目的 URLs conf 文件中声明以下行。
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
现在,如果您检查 rest-framework 的代码,您将在 urls.py 文件中找到以下代码
urlpatterns = [
url(r'^login/$', login, login_kwargs, name='login'),
url(r'^logout/$', logout, name='logout'),
]
我们在项目中为 URL 模式使用了“登录”名称,并且 Django-rest-framework 将相同的名称用于他们的 URL 模式之一。当你使用 reverse('login') 时,Django 会感到困惑。
为了解决这类问题,我们使用命名空间。
@register.simple_tag
def optional_docs_login(request):
"""
Include a login snippet if REST framework's login view is in the URLconf.
"""
try:
login_url = reverse('rest_framework:login')
except NoReverseMatch:
return 'log in'
命名空间的 URL 名称永远不会与其他命名空间发生冲突。
可以使用命名空间 URL 模式反转reverse('namespace:url_name')
我们还利用中间件中的命名空间来不同地处理某些
def process_response(self, request, response):
try:
if resolve(request.path).namespace == 'special_namespace':
response['Custom-Header'] = 'Custom-Value'
return response
except Resolver404:
return response