Маршрутизация Flask

Маршрутизация — одна из ключевых возможностей веб-фреймворков; она определяет, какой URL обрабатывается какой функцией.

Маршрутизация Flask — это механизм в веб-приложениях, который сопоставляет URL с функциями Python.

Маршрутизация Flask — это основная часть приложения Flask, используемая для обработки запросов по разным URL и передачи обработки запроса соответствующим функциям представления.

Ниже приведено подробное описание маршрутизации Flask, включая определения маршрутов, параметры, методы и правила.


Базовая маршрутизация

Использование@app.route()Декоратор привязывает URL-путь к функции представления:

Пример

from flask import Flask

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, и соответствующие параметры автоматически передаются в функцию представления.

Строковая переменная (тип по умолчанию)

Если тип не указан, переменная по умолчанию является строкой и соответствует чему угодно, кроме слеша./Любой символ, кроме:

Пример

# <username> — это динамическая переменная; Flask передает ее значение в функцию представления как именованный параметр.
@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-строка

Пример

# int-конвертер: Совпадать могут только цифры; /post/abc возвращает 404
@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/Это напрямую влияет на поведение сопоставления маршрутов, и многие новички путаются в этом.

Пример

# Правило 1: заканчивается на / — аналогично каталогу
# Обращение к /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, автоматически обновится
  • Автоматически обрабатывает экранирование специальных символов
  • Сгенерированный путь всегда является абсолютным путём

Пример

from flask import Flask, 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:

Пример

from flask import Flask, request

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.route("/login", methods=["GET"])
@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Методы обычно обрабатываются автоматически.


Привязка нескольких маршрутов одновременно

Одну и ту же функцию представления можно привязать к нескольким маршрутам:

Пример

# Два разных URL указывают на одну и ту же функцию представления
@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"。

Другие расширения