Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Маршрутизация Python: Веб-разработка (Flask)

Редкий сайт работает так, что пользователи открывают домашнюю страницу и за её пределы не выходят. Гораздо чаще встречается ситуация, когда браузер запрашивает самые разные данные по разным путям в рамках одного и того же доменного имени.

А ещё пользователи любят "человекочитаемые" пути. Если машине в конечном итоге всё равно, какую строку разбирать, то человеку гораздо проще понять URL вида "shop.com/catalog/food/snacks", чем "shop.com/7d52ae33/8e6d/2d30c16044ac"! Кроме того хорошо структурированные пути помогают разработчику ориентироваться в Web-приложении. Вот почему работа с путями, т.е. маршрутизация — или как ещё говорят, роутинг (routing) — одна из самых важных функций любого Web-фреймворка!

Пути к файлам VS программная маршрутизация

Так уж повелось, что изначально пути в URL означали в первую очередь пути файлам на диске той машины, которая выступала в роли сервера. Сервер просто отдавал файлы по запросу и даже мог выводить содержимое директории, если вдруг путь указывал на неё. Более того подобные сайты до сих пор можно встретить. Устроены они просто и работают надёжно.

Однако выставлять наружу структуру директорий и файлов хочется не всем. Да и менять что-то радикально после того, как пользователи начнут активно пользоваться сайтом, непросто. У пользователей могут остаться закладки или открытые в браузере вкладки, ссылающиеся на старые версии изменившихся путей!

Поэтому подход "пути соответствуют файлам и папкам" используют только для настоящих файлов — изображений, таблиц стилей (CSS-файлов), файлов с JS-кодом. Раздачей таких файлов как правило занимается специальный сервер статики, но об этом я расскажу позже.

Тот же контент, который получается программным путём — шаблонизированный HTML или генерируемый JSON — отдаёт Web-application. Физических HTML-файлов при этом может и не быть — содержимое страниц создаётся в памяти программы и тут же отдаётся по сети. Так получаются "программные маршруты", которые могут выглядеть вполне "по-файловому" — /blog/posts/2020-01-01.html — но никаким физическим файлам и директориям не соответствуют.

Статические пути

Самыми простыми из программных путей являются статические. Каждый такой путь — никогда не меняющаяся строка. Вот регистрация пары таких путей:

@app.route('/')
def index():
    # …

@app.route('/data/users.json')
def users():
    # …

Каждый путь состоит из сегментов — строк, разделённых слешами (slash, "/"). У статического пути все сегменты — фиксированные строки.

Функции index и users в примере — обработчики. А каждое применение декоратора route — добавление нового правила маршрутизации. В этом примере правила максимально просты. Каждое из них звучит так: "если запрошен такой-то статический адрес, то будет вызван этот обработчик".

Динамические пути

Статический путь становится динамическим, если в него включают переменные части пути (variable sections). Выглядит это так:

@app.route('/user/<username>')
def show_user_profile(username):
    return username

@app.route('/post/<int:post_id>')
def show_post(post_id):
    return str(post_id)

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    return subpath

Первое правило берёт сегмент пути (подстроку до ближайшего символа / или до конца строки), идущий следом за /user/, и передаёт в именованный аргумент "username" обработчика в виде строки. При этом содержимое этого самого сегмента никак не проверяется и не обрабатывается.

Два других правила указаны в формате <converter:argument>. В таких случаях значение аргумента будет обработано с помощью указанного преобразователя (converter). Если преобразование прошло успешно, в обработчик попадёт уже преобразованное значение. Если же преобразование завершилось с ошибкой, то до обработчика дело не дойдёт, а в ответ на запрос будет отправлена страница с кодом 404 ("Not Found").

Упомянутый в коде конвертер int очень прост. Он ожидает на входе сегмент, который можно превратить в целое число. А вот конвертер path более интересен. Он позволяет захватить (capture) в переменную часть несколько сегментов за раз, но как минимум один.

path, как говорят, "не жадный" — он захватывает минимально возможное количество сегментов. Это становится важно, когда вы используете комбинации с другими динамическими сегментами. Так правило /<path:p1>/<path:p2> всегда будет захватывать ровно один сегмент в p1 и все остальные в p2 (минимальный путь, для которого сработает это правило, должен содержать два сегмента).

Помимо path и int ещё доступны конвертеры string (он также используется, если не указан никакой другой), float (захватывает числа с плавающей точкой), uuid (захватывает UUID).

Ещё существует конвертер any, подразумевающий "любой из ранее перечисленных". Он попробует вернуть UUID или число, а если не получится, то один или несколько сегментов в виде строки. Этот конвертер используют редко, так как большинство реальных обработчиков не такие уж и "всеядные".


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.

Об обучении на Хекслете

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
900
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 130 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов
Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Python-разработчик
Профессия
Разработка веб-приложений на Django
1 июня 10 месяцев

Используйте Хекслет по максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Даю согласие на обработку персональных данных, соглашаюсь с «Политикой конфиденциальности» и «Условиями оказания услуг»