2013-10-04 9 views
24

Sto studiando la documentazione di Django ma devo entrare in una parte che non riesco a capire che tipo di problema si sta risolvendo e la documentazione non è chiara per me. Chiunque lo sappia, potresti per favore fornirmi un esempio reale di come usare lo spazio dei nomi in un vero problema. Conosco la sintassi ma non conosco lo scopo di questo .. Non potrei capire. GrazieUn vero esempio di spazio dei nomi dell'URL

risposta

30

In genere, vengono utilizzati per inserire gli URL di ciascuna applicazione nel proprio spazio dei nomi. Ciò impedisce alla funzione reverse() di Django e alla funzione modello {% url %} di restituire l'URL errato perché il nome del pattern URL è coincidente con un'altra app.

Quello che ho in mio progetto a livello urls.py file è il seguente:

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

Nota l'ultima sezione: questo passa attraverso le applicazioni che ho installato (settings.LOCAL_APPS è un'impostazione ho aggiunto che contiene solo le mie applicazioni ; viene aggiunto a INSTALLED_APPS che ha altre cose come South), cerca uno urls.py in ognuna di esse e importa quegli URL in uno spazio dei nomi chiamato dopo l'app, e li inserisce anche in una sottodirectory di URL chiamata dopo l'app.

Così, per esempio, se ho un app di nome hosts, e hosts/urls.py si presenta come:

from django.conf.urls.defaults import * 

urlpatterns = patterns('hosts.views', 
    url(r'^$', 'show_hosts', name='list'), 
) 

Ora il mio views.py può chiamare reverse("hosts:list") per ottenere l'URL della pagina che richiama hosts.views.show_hosts, e sembrerà qualcosa come "/hosts/". Lo stesso vale per {% url "hosts:list" %} in un modello. In questo modo non devo preoccuparmi di entrare in collisione con un URL chiamato "elenco" in un'altra app, e non devo prefisso ogni nome con hosts_.

Si noti che la pagina di accesso è {% url "login" %} poiché non è stato assegnato uno spazio dei nomi.

+2

vedo .. ma questo è lo stesso di mettere un nome in un URL, giusto? Fai lo stesso lavoro .. –

+1

Ora ho visto la risposta completa ... ed è fantastico ...Se ho capito bene, tu usi lo spazio dei nomi insieme all'URL con nome ... in modo che non ti preoccupi se hai nominato due viste da differenti app con lo stesso nome ... vero? –

+1

Praticamente. Sono sicuro che ci sono altri usi, e migliori, ma questo è stato un rapido esempio. –

0

consideri che si sta utilizzando un modello di URL, di seguito
url(r'^login/',include('app_name', name='login'))

anche considerare che si sta utilizzando un'applicazione di terze parti come Django-RestFramework. Quando si utilizza l'app, è necessario dichiarare la seguente riga nel file conf degli URL del progetto.

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 

Ora, se si controlla il codice di riposo-quadro, si trova il codice qui sotto nel file di urls.py

urlpatterns = [ 
    url(r'^login/$', login, login_kwargs, name='login'), 
    url(r'^logout/$', logout, name='logout'), 
] 

Abbiamo usato 'login' nome per un modello di URL nel nostro progetto e lo stesso nome viene utilizzato da Django-rest-framework per uno dei loro pattern URL. Quando usi reverse ('login'), Django si confonderà.
Per risolvere questo tipo di problemi, utilizziamo namespace.

@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' 

I nomi di URL di uno spazio dei nomi non scontreranno mai con altri spazi dei nomi.
Un pattern URL namespace può essere invertito utilizzando
reverse('namespace:url_name')