Маршруты и view-функции

View-функция — это обычная функция Python, привязанная к URL. Когда приходит запрос на этот адрес, Flask вызывает функцию и отдаёт её результат браузеру.
Маршрут — это правило «такой-то URL обслуживает такая-то функция». Декоратор @app.route регистрирует правило, view-функция формирует ответ. Всё веб-приложение — это набор таких пар.

Связь URL и кода — сердце любого фреймворка. В Flask она задаётся декоратором над функцией. Декоратор не меняет функцию, он лишь говорит Flask: «адрес / обслуживает index». Сама функция остаётся обычной — её можно вызвать и в тесте напрямую.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return "Главная страница"

@app.route("/about")
def about():
    return "О проекте"

Что может вернуть view-функция? Чаще всего строку (станет телом ответа со статусом 200), либо результат render_template (готовый HTML), либо кортеж (тело, статус, заголовки), либо объект Response для тонкого контроля, либо словарь — Flask сам сериализует его в JSON. Это гибкость, которую ценят за лаконичность.

@app.route("/json")
def as_json():
    return {"status": "ok", "count": 3}   # станет JSON автоматически

@app.route("/teapot")
def teapot():
    return "Я чайник", 418               # тело + статус-код

Полезно держать в голове разделение ответственности: маршрут отвечает за «когда вызвать», view — за «что вернуть», а формирование ответа Flask берёт на себя. Чем тоньше view-функция, тем легче её читать и тестировать: в идеале она достаёт данные, передаёт их в сервис или шаблон и возвращает результат. Как только во view появляется длинная бизнес-логика, её стоит вынести в отдельный модуль. Помни и про множественность возвращаемых типов — это не хаос, а удобство: строка для простого текста, dict для JSON-API, кортеж когда нужен особый статус, Response когда нужны заголовки или куки. Один и тот же маршрут можно эволюционировать от строки к полноценному шаблону, не меняя его сигнатуру.

Как работает под капотом

Внутри Flask хранит карту правил (URL map). Каждый @app.route добавляет в неё правило: шаблон пути, имя функции (endpoint) и разрешённые методы. Когда приходит запрос, Werkzeug сопоставляет путь с правилами и находит нужный endpoint.

  Запрос GET /about
       │
       ▼
  ┌──────────────────────┐
  │  URL map (правила)    │
  │  "/"      → index     │
  │  "/about" → about  ◀──┤ совпало
  │  "/json"  → as_json   │
  └──────────────────────┘
       │
       ▼
  вызвать about() → "О проекте"
       │
       ▼
  обернуть в Response(200, text/html) → браузеру

То, что вернула функция, проходит через «нормализацию ответа»: строка превращается в Response со статусом 200 и типом text/html, словарь — в JSON, кортеж разбирается на части. Эту логику смоделируем на чистом Python.

def make_response(result):
    # имитируем, как Flask превращает результат view в ответ
    if isinstance(result, tuple):
        body, status = result[0], result[1]
        return {"status": status, "body": str(body), "type": "text/html"}
    if isinstance(result, dict):
        import json
        return {"status": 200, "body": json.dumps(result), "type": "application/json"}
    return {"status": 200, "body": str(result), "type": "text/html"}

print(make_response("Привет"))
print(make_response(("Чайник", 418)))
print(make_response({"ok": True}))

Запусти — увидишь три разных ответа из трёх разных типов результата. Это ровно то правило нормализации, что применяет Flask.

Частые ошибки

  • Две функции с одинаковым именем. Имя функции — это endpoint; дубликаты ломают url_for. Давай уникальные имена.
  • Забыть return. View без return возвращает None → ошибка «view did not return a valid response».
  • Возвращать сложные объекты «как есть». Только str, dict, Response, кортеж или то, что Flask умеет нормализовать.

Best practices

  • Имя функции = смысл endpoint, по нему строятся ссылки через url_for.
  • Держи view-функции тонкими: бизнес-логику выноси в отдельные модули/сервисы.
  • Для JSON-ответов возвращай dict — это чище, чем ручной jsonify в простых случаях.

Что запомнить

  • View-функция — обычная функция Python, привязанная к URL декоратором route.
  • Она может вернуть строку, dict (→JSON), кортеж (тело, статус) или Response.
  • Имя функции — это endpoint, по нему строятся ссылки через url_for.
  • Flask нормализует возвращённое значение в HTTP-ответ.

Итог: view-функция — обычная функция, привязанная к URL декоратором route. Она возвращает строку, словарь, кортеж или Response, а Flask нормализует это в HTTP-ответ. Дальше добавим в URL переменные части.

Проверьте себя
1. Что произойдёт, если view-функция вернёт словарь?
AОшибка 500
BFlask сериализует его в JSON-ответ
CСловарь выведется как текст repr
DЗапрос зациклится
2. Чем является имя view-функции для Flask?
AПросто комментарием
BEndpoint, по которому строятся ссылки через url_for
CHTTP-методом
DНазванием шаблона