Краткое содержание предыдущих лекций
Мы уже узнали, что такое представления (views) и как они работают в Django. Вы научились создавать функции представлений и связывать их с URL-адресами через urls.py. Мы разобрали, что такое URLConf и как он помогает маршрутизировать запросы в проекте. Всё это позволило вам понять, как обрабатывать запросы от пользователей и возвращать данные через ваш Django-приложение.
Сегодня мы углубимся в два мощных инструмента маршрутизации: функции path() и re_path(). Они позволяют указать, какие URL-адреса будут обрабатываться, какими представлениями, с возможностью добавления параметров и даже использования регулярных выражений.
path(): лучший друг в мире маршрутизации
Что такое path()
path() — это основной инструмент для маршрутизации URL в современных версиях Django (с версии 2.0). Он был создан, чтобы заменить старую и сложную функцию url() из предыдущих версий Django, сделав маршрутизацию более понятной и удобной.
Синтаксис path():
path(route, view, kwargs=None, name=None)
route— это строка, задающая шаблон URL.view— представление, которое будет вызвано, если шаблон соответствует запросу.kwargs— дополнительные аргументы, которые можно передать в представление (реже используется).name— имя маршрута, которое удобно использовать для создания обратных ссылок.
Пример использования path()
Создадим приложение blog и добавим маршруты в его файле urls.py:
from django.urls import path
from . import views # Импортируем наши представления
urlpatterns = [
path('articles/', views.article_list, name='article_list'), # Маршрут для списка статей
path('articles/<int:id>/', views.article_detail, name='article_detail'), # Маршрут для отдельной статьи
]
Обратите внимание на <int:id> — это динамическая часть URL, которая позволяет извлекать параметр ID.
Теперь создадим соответствующие представления в файле views.py:
from django.http import HttpResponse
def article_list(request):
return HttpResponse("Список статей")
def article_detail(request, id):
return HttpResponse(f"Статья с ID {id}")
При переходе по адресу /articles/, вы увидите текст "Список статей", а, например, по адресу /articles/42/ — "Статья с ID 42".
Типы конвертеров в path()
В path() можно использовать типы конвертеров для динамических URL. Это определяет тип данных, который будет передан в представление. Вот основные конвертеры:
| Конвертер | Описание |
|---|---|
int |
Целое число (0 или 42) |
str |
Строка (по умолчанию, если не указать тип) |
slug |
"Чистый" текст: буквы, цифры, дефисы |
uuid |
UUID — универсальный уникальный идентификатор |
path |
Строка, которая также включает / |
Пример использования конвертеров:
urlpatterns = [
path('user/<int:id>/', views.user_detail), # id — только целое число
path('post/<slug:slug>/', views.post_detail), # slug — только корректный slug
]
Обработка ошибок с path()
Если пользователь попытается перейти по URL, который не соответствует маршрутам, настроенным в urlpatterns, Django автоматически вернёт ошибку 404. Вы можете кастомизировать эту ошибку, об этом мы поговорим в следующих лекциях.
re_path(): когда простоты path() недостаточно
re_path() используется для более сложных случаев маршрутизации, где вы хотите задать URL с помощью регулярных выражений. В отличие от path(), этот инструмент даёт больше гибкости, но требует знаний регулярных выражений.
Синтаксис re_path() аналогичен path():
re_path(regex, view, kwargs=None, name=None)
regex— регулярное выражение, задающее шаблон URL.view— представление, которое будет вызвано, если регулярное выражение совпадает.kwargsиnameиспользуются так же, как вpath().
Пример использования re_path()
Предположим, что вы хотите разрешить маршруты с двумя типами идентификаторов: либо целое число, либо строка. Здесь пригодится re_path():
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^articles/(?P<id>[0-9]+)/$', views.article_detail, name='article_detail_id'), # ID — только числа
re_path(r'^articles/(?P<slug>[-\w]+)/$', views.article_detail_by_slug, name='article_detail_slug'), # SLUG
]
И соответствующие представления:
def article_detail(request, id):
return HttpResponse(f"Статья с ID {id}")
def article_detail_by_slug(request, slug):
return HttpResponse(f"Статья с SLUG {slug}")
Теперь маршрут /articles/42/ вызовет первое представление, а /articles/my-awesome-article/ вызовет второе.
Когда использовать re_path()
Хотя path() покрывает большинство случаев, есть ситуации, где re_path() незаменим:
- Вам нужно учитывать сложные шаблоны URL (например, сочетание букв и цифр).
- У вас есть устаревший код с регулярными выражениями, и вы не можете его изменить.
- У вас сложная логика маршрутизации, которую нельзя описать конвертерами.
Типичные ошибки с re_path()
При использовании re_path() убедитесь, что ваши регулярные выражения корректны и учитывают все аспекты предполагаемого URL. Например, забыв добавить ^ в начале или $ в конце, вы можете столкнуться с неожиданным поведением, так как такие регулярные выражения будут частично совпадать с другими маршрутами.
Сравнение path() и re_path()
| Функция | Простота использования | Гибкость | Подходит для |
|---|---|---|---|
path() |
Простая и интуитивная | Ограничена типами конвертеров | Большинство случаев |
re_path() |
Требует знаний регулярных выражений | Максимальная гибкость | Сложные шаблоны URL |
Пример реализации: объединяем оба подхода
Для демонстрации создадим приложение, которое будет поддерживать статьи с идентификаторами и категориями.
Файл urls.py:
from django.urls import path, re_path
from . import views
urlpatterns = [
path('articles/', views.article_list, name='article_list'),
path('articles/<int:id>/', views.article_detail, name='article_detail'),
re_path(r'^categories/(?P<name>[-\w]+)/$', views.category_detail, name='category_detail'),
]
Файл views.py:
from django.http import HttpResponse
def article_list(request):
return HttpResponse("Список всех статей")
def article_detail(request, id):
return HttpResponse(f"Детальная информация о статье с ID {id}")
def category_detail(request, name):
return HttpResponse(f"Категория: {name}")
Теперь ваш проект сможет обрабатывать адреса:
/articles/— список статей./articles/42/— статья с ID 42./categories/technology/— категория "technology".
Благодаря таким маршрутам вы сможете настроить свою маршрутизацию максимально подробно. Теперь вы готовы не только обрабатывать "стандартные" запросы через path(), но и справляться со сложными задачами маршрутизации с помощью гибкости re_path(). 🚀
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ