До сих пор мы встречались только со статическими маршрутами. В них нет изменяемых частей — адрес точно совпадает с маршрутом и не меняется. На практике чаще встречаются динамические маршруты.
В этом уроке мы познакомимся с динамическими маршрутами, а также научимся строить маршруты, которые содержат плейсхолдеры.
Динамические маршруты
Чтобы разобраться, как выглядят динамические маршруты, проанализируем адреса некоторых курсов на Хекслете:
- https://ru.hexlet.io/courses/php-introduction-to-oop
- https://ru.hexlet.io/courses/php-object-oriented-design
- https://ru.hexlet.io/courses/js-react
В этих адресах прослеживается определенная структура: /courses/<имя курса>. Если предположить, что на каждый такой адрес создается свой маршрут и обработчик, тогда представьте процесс наполнения сайта. Когда будет добавляться каждый новый курс, придется программировать. И хотя курсов у нас не тысячи, такой процесс все равно трудоемок.
То же самое можно сказать и про профили пользователей: /u/<никнейм пользователя>. Причем пользователей сотни тысяч и добавляются они на сайт непрерывно без нашего участия.
В примерах выше мы столкнулись с динамическими маршрутами. У таких маршрутов внутри изменяемые части, но обработчик у маршрута только один. Например, все указанные выше адреса курсов соответствуют одному маршруту, который можно записать так: /courses/{id}
. Где секция {id}
означает, что на это место подставляется конкретный идентификатор курса — уникальная запись, которая отличает одну сущность от другой.
Имя изменяемой части можно выбирать произвольно, например, вместо {id}
можно написать {lala}
. Сам способ записи зависит от конкретного фреймворка. В Flask для этого используются угловые скобки. Это создает ощущение, что используется интерполяция:
@app.route("/courses/<id>")
def courses_show(id):
return f"Course id: {id}"
curl localhost:8000/courses/132
Course id: 132
Плейсхолдеры
Любая изменяемая часть маршрута называется плейсхолдером — заполнитель. В маршруте выше только один плейсхолдер — id
. Доступ к значению конкретного плейсхолдера осуществляется по имени переданного в обработчик аргумента, который должен совпадать с именем плейсхолдера.
Для удобства пользователей в адресах стараются использовать не числовые идентификаторы, а текстовые названия. Например, вместо /courses/332 показывают /courses/php-mvc. Эту часть адреса называют Slug.
Slug должен быть уникален, а его формат должен соответствовать требованиям формирования адресов. Обычно при составлении этих имен используют символы латинского алфавита с дефисом между ними: this-that-other-outre-collection.
Flask позволяет в маршруте указать тип данных, которым может быть плейсхолдер как <тип данных:маршрут>.
string |
(по умолчанию) принимает любой текст без слешей |
int |
принимает только положительные целые числа |
float |
принимает положительные числа |
path |
подобен string, но также можно указывать слеш |
uuid |
принимает UUID-строки |
Количество плейсхолдеров в маршруте может быть больше одного. Обычно такие маршруты используются для вложенных ресурсов:
@app.route("/courses/<int:course_id>/lessons/<int:lesson_id>")
def lessons_show(course_id, lesson_id):
return f"Course id: {course_id}, Lesson id: {lesson_id}"
curl localhost:5000/courses/12/lessons/42
Course id: 12, Lesson id: 42
Понятия адрес и маршрут обозначают разные вещи. Если маршрут статический, то он всегда совпадает с адресом, например, /about. Если маршрут динамический, то ему могут соответствовать бесконечное число адресов. Такое возможно, даже если таких страниц на сайте нет, например, /courses/:id.
Самостоятельная работа
- Добавьте в example.py обработчик из первого примера этого урока
- Откройте в браузере страницу /courses/5. Попробуйте поменять число
Эталонное приложение
Дополнительные материалы
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.