2013-10-04 28 views
24

我正在學習Django文檔,但我得到了一部分,我無法理解它解決了什麼樣的問題,並且文檔不清楚。任何人都知道,請你給我提供一個真正的例子,說明如何在真正的問題中使用命名空間。我知道語法,但我不知道這個目的..我無法理解。謝謝URL命名空間的一個真實例子

回答

30

通常,它們用於將每個應用程序的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,並將這些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" %},因爲它沒有被賦予命名空間。

+2

我看到逆轉..但是這是一樣的把一個名字爲網址,對不對?做同樣的工作.. –

+1

現在我看到了完整的答案......這真是太棒了......如果我說得對,你可以使用命名空間和命名的URL ..這樣你就不用擔心你是否從同名的不同應用程序中命名了兩個視圖......這是正確的嗎? –

+1

非常。我相信還有其他用途,還有更好的,但這是一個很快的例子。 –

0

考慮您使用的URL模式如下
url(r'^login/',include('app_name', name='login'))

還考慮您正在使用第三方應用程式,例如Django的RestFramework。 當您使用應用程序時,您必須在項目的URLs conf文件中聲明以下行。現在

url(r'^api-auth/', include('rest_framework.urls', namespace='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')

相關問題