Django
Маршрутизация URL
Поиск…
Как Django обрабатывает запрос
Django обрабатывает запрос путем маршрутизации входящего URL-пути к функции просмотра. Функция просмотра отвечает за возврат ответа обратно клиенту, выполняющему запрос. Различные URL-адреса обычно обрабатываются различными функциями просмотра. Чтобы перенаправить запрос на определенную функцию просмотра, Django просматривает вашу конфигурацию URL (или URLconf для краткости). Шаблон проекта по умолчанию определяет URLconf в <myproject>/urls.py
.
Ваш URLconf должен быть модулем python, который определяет атрибут с именем urlpatterns
, который является списком django.conf.urls.url()
. Каждый экземпляр url()
должен, как минимум, определять регулярное выражение (регулярное выражение) для сопоставления с URL-адресом и цель, которая является либо функцией просмотра, либо другим URL-интерфейсом. Если шаблон URL нацелен на функцию просмотра, рекомендуется дать ему имя, чтобы легко ссылаться на шаблон позже.
Давайте рассмотрим базовый пример:
# 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'),
]
Этот URLconf определяет три шаблона URL-адресов: все таргетинг на представление: home
страница, информация about
blog-detail
и blog-detail
.
-
url(r'^$', home, name='home'),
Регулярное выражение содержит стартовый якорь '^', за которым следует конечный якорь '$'. Этот шаблон будет соответствовать запросам, где путь URL-адреса является пустой строкой, и myapp.views
их в представление home
определенное в myapp.views
.
-
url(r'^about/$', about, name='about'),
Это регулярное выражение содержит стартовый якорь, за которым следует буквальная строка about/
и конечный якорь. Это будет соответствовать URL /about/
и маршрут к about
представлении. Поскольку каждый непустой URL-адрес начинается с /
, Django удобно разрезает первую косую черту для вас.
-
url(r'^blog/(?P<id>\d+)/$', blog_detail, name='blog-detail'),
Это регулярное выражение немного сложнее. Он определяет стартовый якорь и буквенный строковый blog/
, как и предыдущий шаблон. Следующая часть (?P<id>\d+)
называется группой захвата. Группа захвата, как и его название, фиксирует часть строки, а Django передает захваченную строку в качестве аргумента функции просмотра.
Синтаксис группы захвата - это (?P<name>pattern)
. name
определяет имя группы, которое также является именем, которое Django использует для передачи аргумента в представление. Шаблон определяет, какие символы соответствуют группе.
В этом случае имя является id
, поэтому функция blog_detail
должна принимать параметр с именем id
. Шаблон равен \d+
. \d
означает, что шаблон соответствует только номерам символов. +
означает, что шаблон должен соответствовать одному или нескольким символам.
Некоторые общие закономерности:
Шаблон | Используется для | Матчи |
---|---|---|
\d+ | Я бы | Один или несколько числовых символов |
[\w-]+ | слизень | Один или несколько буквенно-цифровых символов, подчеркивание или тире |
[0-9]{4} | год (длинный) | Четыре числа, от нуля до девяти |
[0-9]{2} | год (короткий) месяц день месяца | Два числа, от нуля до девяти |
[^/]+ | сегмент пути | Все, кроме косой черты |
Группа захвата в шаблоне blog-detail
сопровождается литералом /
и конечным якорем.
Допустимые URL-адреса:
-
/blog/1/ # passes id='1'
-
/blog/42/ # passes id='42'
Недействительными URL-адресами являются, например:
-
/blog/a/ # 'a' does not match '\d'
-
/blog// # no characters in the capturing group does not match '+'
Django обрабатывает каждый шаблон URL в том же порядке, который определен в urlpatterns
. Это важно, если несколько шаблонов могут совпадать с одним и тем же URL. Например:
urlpatterns = [
url(r'blog/(?P<slug>[\w-]+)/$', blog_detail, name='blog-detail'),
url(r'blog/overview/$', blog_overview, name='blog-overview'),
]
В приведенном выше URLconf второй шаблон недоступен. Шаблон будет соответствовать URL /blog/overview/
, но вместо вызова вида blog_overview
URL-адрес сначала будет соответствовать шаблону blog-detail
и вызовет представление blog_detail
с аргументом slug='overview'
.
Чтобы убедиться, что URL /blog/overview/
перенаправлен в представление 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'),
]
Задайте пространство имен URL для многоразового приложения (Django 1.9+)
Настройте URLconf вашего приложения для автоматического использования пространства имен URL, установив атрибут 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'),
]
Это установит пространство имен приложений на 'myapp'
когда оно будет включено в корневой URLconf>. Пользователю вашего многоразового приложения не нужно выполнять какую-либо конфигурацию, кроме как включать ваши URL-адреса:
# In <myproject>/urls.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^myapp/', include('myapp.urls')),
]
Теперь ваше многоразовое приложение может отменить URL-адреса, используя пространство имен приложений:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
Корневой URLconf все еще может устанавливать пространство имен экземпляров с параметром namespace
:
# In <myproject>/urls.py
urlpatterns = [
url(r'^myapp/', include('myapp.urls', namespace='mynamespace')),
]
И пространство имен приложений, и пространство имен экземпляров могут использоваться для изменения URL-адресов:
>>> from django.urls import reverse
>>> reverse('myapp:overview')
'/myapp/overview/'
>>> reverse('mynamespace:overview')
'/myapp/overview/'
Пространство имен экземпляров по умолчанию используется для пространства имен приложений, если оно явно не задано.