Когда мы создаем сайт, пользователи часто переходят не просто на одну страницу, а на множество страниц, зависящих от контекста — например, на страницу конкретного фильма, жанра или года выпуска. Чтобы такие переходы работали гибко, Django поддерживает динамические URL, то есть маршруты, которые могут принимать параметры.
Допустим, мы хотим, чтобы пользователь мог открывать страницу с фильмами определённого жанра. Например:
http://127.0.0.1:8000/genres/1/
http://127.0.0.1:8000/genres/2/
где 1 и 2 — это идентификаторы жанров.
Открой файл cinemahub/urls.py и добавь маршрут с параметром:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index),
path('genres/<int:genre_id>/', views.genres),
]Здесь <int:genre_id> — это динамическая часть URL.
int — это тип передаваемого параметра (только числа),
а genre_id — имя переменной, которую Django передаст в функцию-представление.
Теперь создадим саму функцию genres в файле views.py:
from django.http import HttpResponse
def genres(request, genre_id):
return HttpResponse(f"<h1>Фильмы по жанрам</h1><p>ID жанра: {genre_id}</p>")Функция получает два аргумента:
request— объект запроса (о нём мы уже говорили),genre_id— то самое значение из URL.
Теперь если открыть в браузере адрес
http://127.0.0.1:8000/genres/1/,
то вы увидите текст:
Фильмы по жанрам
ID жанра: 1
Поздравляю 🎉 — вы только что создали динамический маршрут!
Django предоставляет несколько встроенных типов для параметров:
| Конвертер | Что принимает | Пример |
|---|---|---|
str |
Любая непустая строка (без /) |
movies/action/ |
int |
Целое число (включая 0) | genres/3/ |
slug |
"Слаг" — буквы, цифры, дефисы, подчёркивания | movies/the-dark-knight/ |
uuid |
UUID-идентификатор | films/550e8400-e29b-41d4-a716-446655440000/ |
path |
Любая строка, включая / |
files/path/to/video/ |
Совет: Используйте
intдля идентификаторов, аslug— для человеко-понятных адресов (например,the-dark-knight).
Если в одном приложении могут встречаться разные типы параметров, порядок маршрутов имеет значение. Django проверяет пути сверху вниз, и первый совпавший — срабатывает.
urlpatterns = [
path('genres/<int:genre_id>/', views.genres_by_id),
path('genres/<slug:genre_slug>/', views.genres_by_slug),
]Если поменять порядок, то строковые адреса могут "перехватывать" числовые, поэтому всегда размещайте более конкретные маршруты выше.
Иногда стандартных конвертеров недостаточно. Например, в нашем проекте Cinemahub может понадобиться отобразить архив фильмов по году выпуска.
Создадим свой конвертер, который будет принимать четырёхзначный год.
- В папке приложения
cinemahubсоздайте файлconverters.py:
class FourDigitYearConverter:
regex = "[0-9]{4}" # Регулярное выражение: четыре цифры
def to_python(self, value):
# Преобразуем строку в число
return int(value)
def to_url(self, value):
# Преобразуем число обратно в строку при генерации URL
return f"{value:04d}"- Зарегистрируйте конвертер в
urls.py:
from django.urls import path, register_converter
from . import converters, views
# Регистрируем собственный конвертер
register_converter(converters.FourDigitYearConverter, 'year4')
urlpatterns = [
path('', views.index),
path('archive/<year4:year>/', views.archive),
]- Добавьте функцию-представление в
views.py:
from django.http import HttpResponse
def archive(request, year):
print(f"Архив за {year} год") # Проверим работу конвертера в консоли
return HttpResponse(f"<h1>Архив фильмов за {year} год</h1>")- Запустите сервер и перейдите по адресу:
http://127.0.0.1:8000/archive/2020/
В браузере вы увидите:
Архив фильмов за 2020 год
А в консоли, где запущен сервер, появится строка:
Архив за 2020 год
Это подтверждает, что параметр успешно преобразовался в число — ведь строка "2020" в Python превратилась в int(2020).
Чтобы убедиться, что маршруты работают, проверьте следующие адреса в браузере:
| Адрес | Ожидаемый результат |
|---|---|
http://127.0.0.1:8000/genres/3/ |
Выведет ID жанра |
http://127.0.0.1:8000/archive/2021/ |
Отобразит архив за 2021 год |
Если страница открывается — значит всё сделано правильно ✅.
Теперь вы знаете, как Django позволяет создавать динамические URL — гибкие маршруты, которые могут принимать параметры и использовать их внутри представлений. А пользовательские конвертеры помогут описывать более сложные правила — например, фильтрацию по году, месяцу или даже коду IMDb.
- Что такое динамический URL и зачем он нужен?
- Как в Django передать параметр из адреса в функцию-представление?
- Какие типы конвертеров поддерживаются по умолчанию?
- Почему порядок маршрутов в
urls.pyимеет значение? - Что делает метод
to_python()в пользовательском конвертере? - Как проверить в консоли, что конвертер сработал правильно?
- Что произойдет, если не зарегистрировать пользовательский конвертер через
register_converter? - Какой адрес отобразит страницу архива фильмов за 2024 год?
- Что делает метод
to_url()в пользовательском конвертере? - Для чего может пригодиться
slug-конвертер в проекте Cinemahub?