Skip to content

Latest commit

 

History

History
202 lines (137 loc) · 9.1 KB

File metadata and controls

202 lines (137 loc) · 9.1 KB

Модуль 1. Урок 4. Динамические URL и пользовательские конвертеры

Когда мы создаем сайт, пользователи часто переходят не просто на одну страницу, а на множество страниц, зависящих от контекста — например, на страницу конкретного фильма, жанра или года выпуска. Чтобы такие переходы работали гибко, Django поддерживает динамические URL, то есть маршруты, которые могут принимать параметры.


Динамические 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

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 может понадобиться отобразить архив фильмов по году выпуска.

Создадим свой конвертер, который будет принимать четырёхзначный год.

  1. В папке приложения 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}"
  1. Зарегистрируйте конвертер в 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),
]
  1. Добавьте функцию-представление в views.py:
from django.http import HttpResponse

def archive(request, year):
    print(f"Архив за {year} год")  # Проверим работу конвертера в консоли
    return HttpResponse(f"<h1>Архив фильмов за {year} год</h1>")
  1. Запустите сервер и перейдите по адресу:
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.


Вопросы для самопроверки

  1. Что такое динамический URL и зачем он нужен?
  2. Как в Django передать параметр из адреса в функцию-представление?
  3. Какие типы конвертеров поддерживаются по умолчанию?
  4. Почему порядок маршрутов в urls.py имеет значение?
  5. Что делает метод to_python() в пользовательском конвертере?
  6. Как проверить в консоли, что конвертер сработал правильно?
  7. Что произойдет, если не зарегистрировать пользовательский конвертер через register_converter?
  8. Какой адрес отобразит страницу архива фильмов за 2024 год?
  9. Что делает метод to_url() в пользовательском конвертере?
  10. Для чего может пригодиться slug-конвертер в проекте Cinemahub?

Предыдущий урок | Следующий урок