Django
URL-Routing
Suche…
Wie Django eine Anfrage bearbeitet
Django verarbeitet eine Anfrage, indem der eingehende URL-Pfad an eine Ansichtsfunktion weitergeleitet wird. Die Ansichtsfunktion ist dafür verantwortlich, eine Antwort an den Client zurückzusenden, der die Anfrage abstellt. Unterschiedliche URLs werden normalerweise von verschiedenen Ansichtsfunktionen verarbeitet. Um die Anfrage an eine bestimmte Ansichtsfunktion weiterzuleiten, prüft Django Ihre URL-Konfiguration (oder kurz URLconf). Die Standardprojektvorlage definiert die URLconf in <myproject>/urls.py
.
Ihre URLconf sollte ein Python-Modul sein, das ein Attribut namens urlpatterns
definiert. urlpatterns
handelt es sich um eine Liste von django.conf.urls.url()
. Jede url()
Instanz muss mindestens einen regulären Ausdruck (einen regulären Ausdruck ) definieren, der mit der URL abgeglichen werden soll, sowie ein Ziel, bei dem es sich entweder um eine Ansichtsfunktion oder eine andere URLconf handelt. Wenn ein URL-Muster auf eine Ansichtsfunktion abzielt, empfiehlt es sich, ihm einen Namen zu geben, um das Muster später leicht referenzieren zu können.
Schauen wir uns ein einfaches Beispiel an:
# 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'),
]
Diese URLconf definiert drei URL - Muster, die alle Targeting eine Ansicht: zu home
, about
und blog-detail
.
-
url(r'^$', home, name='home'),
Der Regex enthält einen Startanker '^', unmittelbar gefolgt von einem Endanker '$'. Dieses Muster wird Anforderungen entsprechen denen der URL - Pfad eine leere Zeichenfolge ist, und sie an die home
Blick in definierten myapp.views
.
-
url(r'^about/$', about, name='about'),
Dieser reguläre Ausdruck enthält einen Startanker, gefolgt von der Literalzeichenfolge about/
und dem Endanker. Dies stimmt mit der URL /about/
überein und leitet sie an die about
Ansicht weiter. Da jede nicht leere URL mit einem /
beginnt, schneidet Django bequem den ersten Schrägstrich für Sie ab.
-
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
Dieser Regex ist etwas komplexer. Es definiert den Startanker und den literalen String- blog/
wie das vorherige Muster. Der nächste Teil (?P<id>\d+)
wird als Erfassungsgruppe bezeichnet. Eine Erfassungsgruppe erfasst, wie der Name vermuten lässt, einen Teil der Zeichenfolge, und Django übergibt die erfasste Zeichenfolge als Argument an die Ansichtsfunktion.
Die Syntax einer Erfassungsgruppe lautet (?P<name>pattern)
. name
definiert den Namen der Gruppe, der auch von Django verwendet wird, um das Argument an die Ansicht zu übergeben. Das Muster definiert, welche Zeichen von der Gruppe gefunden werden.
In diesem Fall lautet der Name id
, daher muss die Funktion blog_detail
einen Parameter namens id
akzeptieren. Das Muster ist \d+
. \d
bedeutet, dass das Muster nur mit Ziffernzeichen übereinstimmt. +
bedeutet, dass das Muster mit einem oder mehreren Zeichen übereinstimmen muss.
Einige gängige Muster:
Muster | Benutzt für | Streichhölzer |
---|---|---|
\d+ | Ich würde | Ein oder mehrere numerische Zeichen |
[\w-]+ | Schnecke | Ein oder mehrere alphanumerische Zeichen, Unterstriche oder Bindestriche |
[0-9]{4} | jahr (lang) | Vier Zahlen, null bis neun |
[0-9]{2} | Jahr (kurz) Monat Monatstag | Zwei Zahlen, null bis neun |
[^/]+ | Wegsegment | Alles außer einem Schrägstrich |
Auf die Erfassungsgruppe im blog-detail
folgen ein Literal /
und der Endanker.
Gültige URLs sind:
-
/blog/1/ # passes id='1'
-
/blog/42/ # passes id='42'
Ungültige URLs sind zum Beispiel:
-
/blog/a/ # 'a' does not match '\d'
-
/blog// # no characters in the capturing group does not match '+'
Django verarbeitet jedes URL-Muster in derselben Reihenfolge, in der sie in URL-Mustern definiert urlpatterns
. Dies ist wichtig, wenn mehrere Muster mit derselben URL übereinstimmen können. Zum Beispiel:
urlpatterns = [
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
url(r'blog/overview/$', blog_overview, name='blog-overview'),
]
In der obigen URLconf ist das zweite Muster nicht erreichbar. Das Muster würde der URL /blog/overview/
, aber anstatt die blog_overview
Ansicht blog_overview
, blog_overview
die URL zuerst mit dem blog-detail
blog_detail
und ruft die blog_detail
Ansicht mit dem Argument slug='overview'
.
Um sicherzustellen, dass die URL /blog/overview/
zur blog_overview
Ansicht geleitet wird, sollte das Muster über dem blog-detail
blog_overview
blog-detail
:
urlpatterns = [
url(r'blog/overview/$', blog_overview, name='blog-overview'),
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
]
Festlegen des URL-Namespaces für eine wiederverwendbare App (Django 1.9+)
Konfigurieren Sie die URLconf Ihrer App für die automatische Verwendung eines URL-Namespaces, indem Sie das Attribut 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'),
]
Dadurch wird der Anwendungsnamespace auf 'myapp'
wenn er in der Stamm-URLconf> enthalten ist. Der Benutzer Ihrer wiederverwendbaren App muss außer den URLs keine weiteren Einstellungen vornehmen:
# In <myproject>/urls.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^myapp/', include('myapp.urls')),
]
Ihre wiederverwendbare App kann jetzt URLs mit dem Anwendungsnamespace umkehren:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
Die Stamm-URLconf kann weiterhin einen Instanz-Namespace mit dem namespace
Parameter festlegen:
# In <myproject>/urls.py
urlpatterns = [
url(r'^myapp/', include('myapp.urls', namespace='mynamespace')),
]
Sowohl der Anwendungs-Namespace als auch der Instanz-Namespace können zum Umkehren der URLs verwendet werden:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
>>> reverse('mynamespace:overview')
'/myapp/overview/'
Der Instanz-Namespace verwendet standardmäßig den Anwendungs-Namespace, wenn er nicht explizit festgelegt ist.