Зарегистрируйтесь, чтобы продолжить обучение

Именованные маршруты Python: Веб-разработка (Flask)

Шаблоны сайта содержат множество внутренних ссылок: от меню до кнопок и форм. До сих пор мы формировали эти ссылки прямо в тех местах, где они нам нужны:

<form action="/users/{{ user['id'] }}" method="post">
  <input type="submit" value="Remove">
</form>

Так же ссылки строятся и в обработчиках, например, при редиректах:

@app.post('/users')
def users_post():
    repo = UserRepository()
    user = request.form.to_dict()
    errors = validate(user)
        ... # Остальной код
    repo.save(user)
    # Тут формируется ссылка
    return redirect(f'/users/{user["id"]}', code=302)

В примерах выше формирование ссылки зашито прямо в то место, где она используется. Такой способ формирования ссылок потенциально опасен. Например, маршрут может измениться с /users/{id} на /u/{id}. Тогда придется пройтись по всем шаблонам и изменить все ссылки /users/{{ user['id'] }} на /u/{{ user['id'] }}.

Если этот маршрут удалить, сайт и приемочные тесты продолжат работать, но ссылки начнут вести на страницы 404. Будет лучше, если страницы с такими ссылками начнут выдавать ошибки. Тогда выявить подобные ссылки станет крайне просто.

Чтобы решить эту задачу, придумали именованные маршруты. Каждому маршруту фреймворка присваивается имя, которое затем можно использовать при построении конкретной ссылки. во Flask в качестве такого имени используется имя обработчика:

from flask import Flask, url_for

app = Flask(__name__)

@app.route('/users/')
def users_index():
    # Код обработчика

@app.route('/users/<id>')
def users_show(id):
    # Код обработчика

@app.route('/')
def index():
    # В функцию передается имя обработчика, а она возвращает url
    url_for('users_index') # /users/
    url_for('users_show', id=3) # /users/3
    # Остальной код

В реальных приложениях ссылки формируются во многих их частях:

  • В шаблонах
  • В обработчиках (при редиректах)
  • В письмах

Поэтому большинство фреймворков предоставляют готовую функцию, которую можно использовать везде, где формируются ссылки. В шаблонах Jinja2 ссылки строятся так:

<h1>User List</h1>
<ul>
    {% for user in users %}
    <li><a href="{{ url_for('users_show', id=user.id) }}">{{ user.name }}</a></li>
    {% endfor %}
</ul>

В качестве первого параметра url_for() передается имя обработчика, а последующими параметрами — необходимые аргументы для функции-обработчика.

Так в шаблоне выше url_for('users_show', id=user.id) заменится на конкретную ссылку этого обработчика с подставленными плейсхолдерами. Например для пользователя с user.id равным 42 подставится ссылка /users/42

Используйте url_for() в шаблонах всегда. Так вы сможете избежать проблемы мертвых ссылок, ситуации, когда url обработчика поменяли в коде, но забыли поменять все старые недействительные ссылки в HTML-страницах.


Самостоятельная работа

  1. Сделайте так, чтобы в обработчиках обращение ко всем маршрутам было через их имена

Эталонное приложение

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

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

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

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

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

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

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

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff