Маршрутизация Flask
Маршрутизация — одна из ключевых возможностей веб-фреймворков; она определяет, какой URL обрабатывается какой функцией.
Маршрутизация Flask — это механизм в веб-приложениях, который сопоставляет URL с функциями Python.
Маршрутизация Flask — это основная часть приложения Flask, используемая для обработки запросов по разным URL и передачи обработки запроса соответствующим функциям представления.
Ниже приведено подробное описание маршрутизации Flask, включая определения маршрутов, параметры, методы и правила.
Базовая маршрутизация
Использование@app.route()Декоратор привязывает URL-путь к функции представления:
Пример
app = Flask(__name__)
# Привязать корневой путь "/"
@app.route("/")
def index():
return "Это главная страница"
# Привязать путь "/hello"
@app.route("/hello")
def hello():
return "Hello, EXAMPLE!"
# Разные пути соответствуют разным функциям
@app.route("/about")
def about():
return "About this site"
Посетитеhttp://127.0.0.1:5000/helloкогда Flask вызываетhello()функцию.
Посетитеhttp://127.0.0.1:5000/aboutкогда Flask вызываетabout()функцию.

Правила переменных
В реальных приложениях URL-адреса часто содержат динамические части, такие как идентификаторы пользователей, заголовки статей и т.д.
Flask использует<variable_name>Синтаксис определяет динамические части в URL, и соответствующие параметры автоматически передаются в функцию представления.
Строковая переменная (тип по умолчанию)
Если тип не указан, переменная по умолчанию является строкой и соответствует чему угодно, кроме слеша./Любой символ, кроме:
Пример
@app.route("/user/<username>")
def show_user(username):
# Примечание: username может содержать вредоносные скрипты; в продакшене требуется экранирование
return f"<h1>User: {username}</h1>"
# Проверка посещений:
# /user/example → страница отображает "User: example"
# /user/EXAMPLE → страница отображает "User: EXAMPLE"
Конвертеры типов
Flask предоставляет несколько встроенных конвертеров, через<type:variable_name>синтаксис:
| Конвертер | Описание | Пример URL | Результат совпадения |
|---|---|---|---|
| string | По умолчанию принимает текст, не содержащий / | /user/example | username = "example" |
| int | Положительное целое число | /post/42 | post_id = 42 |
| float | Положительное число с плавающей точкой | /price/19.99 | price = 19.99 |
| path | Принимает строки, содержащие / | /file/a/b/c.txt | filepath = "a/b/c.txt" |
| uuid | Строка формата UUID | /item/550e8400-e29b-41d4-a716-446655440000 | item_id = UUID-строка |
Пример
@app.route("/post/<int:post_id>")
def show_post(post_id):
# post_id имеет тип int, а не строка
return f"<h1>Статья #{post_id}</h1>"
# path-конвертер: Может сопоставлять пути, содержащие /
@app.route("/file/<path:filepath>")
def show_file(filepath):
return f"<p>Путь к файлу: {filepath}</p>"
# float-конвертер: Сопоставляется с числами с плавающей запятой
@app.route("/price/<float:amount>")
def show_price(amount):
return f"<p>Цена: ¥{amount}</p>"
# конвертер uuid: принимает только стандартный формат UUID
@app.route("/item/<uuid:item_id>")
def show_item(item_id):
return f"<p>ID товара: {item_id}</p>"
Конвертеры не только выполняют проверку типов, но и автоматически преобразуют совпавшие значения в соответствующие типы Python. Например<int:post_id>В функцию представления передаётсяintвместоstr。
Поведение перенаправления при завершающем слэше
в конце URL/Это напрямую влияет на поведение сопоставления маршрутов, и многие новички путаются в этом.
Пример
# Обращение к /projects автоматически перенаправляет с кодом 308 на /projects/
@app.route("/projects/")
def projects():
return "Страница списка проектов"
# Правило 2: не заканчивается на / — похоже на файл
# При обращении к /about/ возвращается 404 Not Found
@app.route("/about")
def about():
return "Страница «О нас»"
| Определение маршрута | Перейдите на /projects | Перейдите на /projects/ |
|---|---|---|
| @app.route("/projects/") | 308 перенаправление на /projects/ | Обычный ответ |
| @app.route("/about") | Обычный ответ | 404 Not Found |
Этот дизайн помогает SEO: он гарантирует, что один и тот же контент имеет только один канонический URL, предотвращая индексацию одной и той же страницы поисковыми системами дважды.
Построение URL — url_for
url_for()— встроенная во Flask функция генерации URL, которая создаёт соответствующий URL на основе имени функции представления.
Это даёт множество преимуществ по сравнению с жёстко заданными строками URL:
- Если маршрут URL будет изменён позже, всё, что генерируется черезurl_for, автоматически обновится
- Автоматически обрабатывает экранирование специальных символов
- Сгенерированный путь всегда является абсолютным путём
Пример
app = Flask(__name__)
@app.route("/")
def index():
return "Главная"
@app.route("/login")
def login():
return "Страница входа"
@app.route("/user/<username>")
def profile(username):
return f"профиль {username}"
# Используйте test_request_context() для имитации контекста запроса
# Это позволяет url_for() правильно генерировать URL
with app.test_request_context():
print(url_for("index")) # Вывод /
print(url_for("login")) # Вывод /login
print(url_for("login", next="/")) # Вывод /login?next=%2F
print(url_for("profile", username="example")) # Вывод /user/example
url_for()Первый параметр — имя функции представления (примечание: это имя функции, а не путь URL).
Если URL содержит динамические переменные, передайте соответствующие значения как именованные аргументы.
Дополнительные неизвестные параметры автоматически добавляются в строку запроса.
Методы HTTP
По умолчанию маршрут отвечает только наGETзапрос.
С помощью параметраmethodsможно указать разрешённые методы HTTP:
Пример
app = Flask(__name__)
# Один и тот же URL отвечает как на GET-, так и на POST-запросы
@app.route("/login", methods=["GET", "POST"])
def login():
# Определить текущий тип запроса с помощью request.method
if request.method == "POST":
# Обработать отправку формы входа (выполняется при POST-запросе)
username = request.form.get("username")
return f"<h1>С возвращением, {username}!</h1>"
else:
# Отобразить форму входа (выполняется при GET-запросе)
return """
<form method="post">
<input type="text" name="username" placeholder="Имя пользователя">
<input type="submit" value="Войти">
</form>
"""
декоратор сокращённого метода
Flask предоставляет сокращённые декораторы для распространённых HTTP-методов, чтобы сделать код более понятным:
Пример
@app.get("/login")
def login_form():
return "<form>...</form>"
# Эквивалентно @app.route("/login", methods=["POST"])
@app.post("/login")
def login_submit():
return "Вход выполнен успешно"
# Также поддерживает @app.put(), @app.delete(), @app.patch()
@app.delete("/post/<int:post_id>")
def delete_post(post_id):
# API для удаления статьи
return f"Статья {post_id} удалена"
| Удобные декораторы | Эквивалентный синтаксис | Типичное использование |
|---|---|---|
| @app.get("/path") | @app.route("/path", methods=["GET"]) | Получение данных, отображение страницы |
| @app.post("/path") | @app.route("/path", methods=["POST"]) | Создание данных, отправка формы |
| @app.put("/path") | @app.route("/path", methods=["PUT"]) | Обновление данных (полная замена) |
| @app.delete("/path") | @app.route("/path", methods=["DELETE"]) | Удаление данных |
| @app.patch("/path") | @app.route("/path", methods=["PATCH"]) | Обновление данных (частичное обновление) |
Автоматически обрабатываетЕсли маршрут определяетGETметод, Flask автоматически добавляет поддержкуHEADподдержки методов. ТакжеOPTIONSМетоды обычно обрабатываются автоматически.
Привязка нескольких маршрутов одновременно
Одну и ту же функцию представления можно привязать к нескольким маршрутам:
Пример
@app.route("/hello")
@app.route("/hello/<name>")
def greet(name=None):
# у name значение по умолчанию None; при посещении /hello name равно None
if name is None:
return "<h1>Hello, World!</h1>"
return f"<h1>Привет, {name}!</h1>"
Посетите/helloкогдаnameиспользует значение по умолчаниюNone, при посещении/hello/exampleкогдаnameравно"example"。
Другие расширения