URL命名空间的一个真实示例

时间:2013-10-04 01:10:07

标签: django url namespaces django-views

我正在研究Django文档,但是我遇到了一个我无法理解的部分:什么是在真实问题中如何使用命名空间的真实示例。我知道语法,但我不知道这个目的。

3 个答案:

答案 0 :(得分:35)

通常,它们用于将每个应用程序的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),在每个URL中查找urls.py,并将这些URL导入到以app命名的命名空间中,并将这些URL放入以app命名的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")来获取调用hosts.views.show_hosts的网页的网址,它看起来像"/hosts/"。模板中的{% url "hosts:list" %}也是如此。这样我就不必担心在另一个应用程序中与名为“list”的URL发生冲突,而且我不必为每个名称添加hosts_前缀。

请注意,登录页面位于{% url "login" %},因为它没有给出命名空间。

答案 1 :(得分:5)

考虑您使用的网址格式如下所示 url(r'^login/',include('app_name', name='login'))

另外请考虑使用像Django-RestFramework这样的第三方应用。 当您使用该应用程序时,您必须在项目的URL 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'),
]

我们已经使用过' login'我们项目中URL模式的名称,Django-rest-framework使用相同的名称来表示其中一种URL模式。当你使用反向(' 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名称永远不会与其他命名空间冲突。
可以使用
reverse('namespace:url_name')

反转命名空间的URL模式

答案 2 :(得分:0)

我们还利用中间件中的命名空间来不同地处理某些

    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