Django
Routing URL
Ricerca…
Come Django gestisce una richiesta
Django gestisce una richiesta instradando il percorso dell'URL in entrata a una funzione di visualizzazione. La funzione di visualizzazione è responsabile di restituire una risposta al client che effettua la richiesta. URL diversi vengono generalmente gestiti da diverse funzioni di visualizzazione. Per indirizzare la richiesta ad una specifica funzione di visualizzazione, Django controlla la configurazione dell'URL (o URLconf in breve). Il modello di progetto predefinito definisce URLconf in <myproject>/urls.py
.
Il tuo URLconf dovrebbe essere un modulo python che definisce un attributo chiamato urlpatterns
, che è una lista di django.conf.urls.url()
di django.conf.urls.url()
. Ogni istanza di url()
deve almeno definire un'espressione regolare (una regex) da abbinare all'URL e una destinazione, che è una funzione di visualizzazione o un URLconf differente. Se un pattern URL ha come target una funzione di visualizzazione, è una buona idea assegnargli un nome per fare facilmente riferimento al modello in un secondo momento.
Diamo un'occhiata a un esempio di base:
# In <myproject>/urls.py
from django.conf.urls import url
from myapp.views import home, about, blog_detail
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^about/$', about, name='about'),
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
]
Questo URLconf definisce tre pattern URL, tutti mirati a una vista: home
, about
e blog-detail
.
-
url(r'^$', home, name='home'),
La regex contiene un'ancora di inizio '^', immediatamente seguita da un'ancora di fine '$'. Questo modello corrisponderà alle richieste in cui il percorso dell'URL è una stringa vuota e le indirizza alla vista home
definita in myapp.views
.
-
url(r'^about/$', about, name='about'),
Questa regex contiene un'ancora di inizio, seguita dalla stringa letterale about/
, e dall'ancora di fine. Questo corrisponderà all'URL /about/
e lo indirizzerà alla visualizzazione about
. Poiché ogni URL non vuoto inizia con un /
, Django taglia comodamente la prima barra per te.
-
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
Questa regex è un po 'più complessa. Definisce l'ancora di partenza e il blog/
stringa letterale blog/
, come il modello precedente. La parte successiva, (?P<id>\d+)
, è chiamata gruppo di cattura. Un gruppo che cattura, come suggerisce il nome, cattura una parte della stringa e Django passa la stringa catturata come argomento alla funzione di visualizzazione.
La sintassi di un gruppo che cattura è (?P<name>pattern)
. name
definisce il nome del gruppo, che è anche il nome che Django usa per passare l'argomento alla vista. Il modello definisce quali caratteri sono abbinati al gruppo.
In questo caso, il nome è id
, quindi la funzione blog_detail
deve accettare un parametro denominato id
. Il modello è \d+
. \d
indica che il modello corrisponde solo ai caratteri numerici. +
significa che il modello deve corrispondere a uno o più caratteri.
Alcuni modelli comuni:
Modello | Usato per | fiammiferi |
---|---|---|
\d+ | id | Uno o più caratteri numerici |
[\w-]+ | lumaca | Uno o più caratteri alfanumerici, trattini bassi o trattini |
[0-9]{4} | anno (lungo) | Quattro numeri, da zero a nove |
[0-9]{2} | anno (breve) mese giorno del mese | Due numeri, da zero a nove |
[^/]+ | segmento del percorso | Qualunque cosa tranne una barra |
Il gruppo di cattura nel modello di blog-detail
del blog-detail
è seguito da un letterale /
e dall'ancora finale.
Gli URL validi includono:
-
/blog/1/ # passes id='1'
-
/blog/42/ # passes id='42'
Gli URL non validi sono ad esempio:
-
/blog/a/ # 'a' does not match '\d'
-
/blog// # no characters in the capturing group does not match '+'
Django elabora ogni pattern URL nello stesso ordine in cui sono definiti in urlpatterns
. Questo è importante se più pattern possono corrispondere allo stesso URL. Per esempio:
urlpatterns = [
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
url(r'blog/overview/$', blog_overview, name='blog-overview'),
]
Nel precedente URLconf, il secondo modello non è raggiungibile. Lo schema corrisponderebbe all'URL /blog/overview/
, ma invece di chiamare la vista blog_overview
, l'URL corrisponderà innanzitutto al modello di blog-detail
del blog-detail
e chiamerà la vista blog_detail
con un argomento slug='overview'
.
Per assicurarsi che l'URL /blog/overview/
sia indirizzato alla vista blog_overview
, lo schema deve essere posizionato sopra il modello dei blog-detail
del blog-detail
:
urlpatterns = [
url(r'blog/overview/$', blog_overview, name='blog-overview'),
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
]
Imposta lo spazio dei nomi URL per un'app riutilizzabile (Django 1.9+)
Configura URLconf della tua app per utilizzare automaticamente uno spazio dei nomi URL impostando l'attributo app_name
:
# In <myapp>/urls.py
from django.conf.urls import url
from .views import overview
app_name = 'myapp'
urlpatterns = [
url(r'^$', overview, name='overview'),
]
Questo imposterà lo spazio 'myapp'
nomi dell'applicazione su 'myapp'
quando è incluso nel root URLconf>. L'utente della tua app riusabile non deve eseguire alcuna configurazione se non includere gli URL:
# In <myproject>/urls.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^myapp/', include('myapp.urls')),
]
La tua app riusabile può ora invertire gli URL utilizzando lo spazio dei nomi dell'applicazione:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
L'URL rootonf può ancora impostare uno spazio dei namespace
dell'istanza con il parametro namespace
:
# In <myproject>/urls.py
urlpatterns = [
url(r'^myapp/', include('myapp.urls', namespace='mynamespace')),
]
Sia lo spazio dei nomi dell'applicazione che lo spazio dei nomi dell'istanza possono essere utilizzati per invertire gli URL:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
>>> reverse('mynamespace:overview')
'/myapp/overview/'
Il namespace dell'istanza si imposta automaticamente sullo spazio dei nomi dell'applicazione se non è impostato in modo esplicito.