Python: уроки, справочник и задачи

Основы Flask для начинающих: первое веб-приложение

Раздел: Flask и Tkinter · Обновлено 31.10.2026

Основы Flask укладываются в несколько понятий: приложение, маршрут, функция-представление, объект запроса и шаблон. В статье по шагам собрано небольшое приложение: установка, обработка адресов с параметрами, чтение данных из GET и POST, ответ в HTML и JSON. В конце показана структура проекта и расширения, которые понадобятся дальше.

Основы Flask
Фото: Akaniji / Public domain, Wikimedia Commons
Содержание статьи
  1. Что такое Flask и когда его выбирать
  2. Установка и минимальное приложение
  3. Маршруты и переменные в URL
    1. Построение ссылок через url_for
  4. Запрос и ответ
  5. Шаблоны Jinja2
  6. Структура проекта и следующие шаги
  7. Частые вопросы
    1. Почему изменения в коде не видны в браузере?
    2. Как сменить порт и открыть сайт с другого устройства?
    3. Подходит ли Flask для API?
    4. Где хранить данные между запросами?

Что такое Flask и когда его выбирать

Flask - микрофреймворк для веб-приложений на Python. Приставка "микро" означает, что в ядре есть только самое нужное: маршрутизация и работа с HTTP на базе библиотеки Werkzeug, шаблонизатор Jinja2 и отладочный сервер. Базы данных, формы, авторизацию и админку подключают отдельными расширениями, поэтому проект содержит только то, что ему действительно нужно.

КритерийFlaskDjango
Минимальное приложениеОдин файл, 5-7 строкПроект из нескольких файлов, создается командой
ORM и админкаПодключаются расширениямиВстроены
Структура проектаСвободнаяЗадана фреймворком
Где удобенAPI, небольшие сайты, прототипы, сервисыКрупные сайты с типовым набором функций

Для старта нужно знать основы Python: функции, словари, декораторы на уровне "что это такое", а также базовый HTML и устройство HTTP-запроса.

Установка и минимальное приложение

Создайте папку проекта, виртуальное окружение и поставьте пакет:

python -m venv .venv
# Windows: .venv\Scripts\activate   Linux и macOS: source .venv/bin/activate
pip install flask

Минимальное приложение помещается в файл app.py:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "<h1>Привет, Flask!</h1>"

if __name__ == "__main__":
    app.run(debug=True)

Запустите его командой python app.py или flask --app app run --debug и откройте в браузере http://127.0.0.1:5000/. Режим отладки перезапускает сервер при изменении кода и показывает трассировку ошибок прямо на странице. Включать его на рабочем сервере нельзя: отладчик позволяет выполнять произвольный код.

Аргумент __name__ подсказывает Flask, где лежит модуль приложения, чтобы найти рядом папки templates и static. Подробный разбор первого запуска с типичными ошибками есть в статье первое приложение на Flask.

Маршруты и переменные в URL

Декоратор @app.route() связывает адрес с функцией-представлением. Часть адреса можно сделать переменной: она передается в функцию аргументом. Конвертер перед именем задает тип и заодно проверяет значение.

@app.route("/user/<name>")
def profile(name):
    return f"Профиль {name}"

@app.route("/post/<int:post_id>")
def post(post_id):
    return f"Статья {post_id}, следующая {post_id + 1}"  # post_id уже int

@app.route("/files/<path:subpath>")
def files(subpath):
    return f"Файл {subpath}"   # путь со слешами

Адрес /post/abc не подойдет под конвертер int, и Flask сам вернет ошибку 404. Кроме int есть string (по умолчанию, без слешей), float, path и uuid.

Построение ссылок через url_for

Функция url_for("post", post_id=5) строит адрес по имени функции-представления и вернет /post/5. Если позже поменять шаблон адреса в декораторе, ссылки в шаблонах и редиректах обновятся автоматически, поэтому адреса в коде вручную не пишут.

Запрос и ответ

По умолчанию маршрут принимает только GET. Чтобы обработать отправку формы, перечислите методы в параметре methods. Данные запроса доступны через объект request: request.args содержит параметры строки адреса, request.form поля формы, request.get_json() тело запроса в формате JSON.

from flask import Flask, request, redirect, url_for, abort

app = Flask(__name__)
NOTES = {1: "Купить хлеб"}

@app.route("/notes", methods=["GET", "POST"])
def notes():
    if request.method == "POST":
        text = request.form.get("text", "").strip()
        if not text:
            abort(400)
        NOTES[max(NOTES) + 1] = text
        return redirect(url_for("notes"))
    limit = request.args.get("limit", default=10, type=int)
    return {"notes": list(NOTES.values())[:limit]}

Функция может вернуть строку (будет HTML), словарь или список (Flask превратит их в JSON с правильным заголовком), а также кортеж вида (тело, код_ответа), например return "Создано", 201. Функция abort(404) прерывает обработку и отдает страницу ошибки, redirect() перенаправляет браузер на другой адрес.

После успешного POST принято делать редирект на GET-страницу. Тогда обновление страницы в браузере не отправит форму повторно.

Шаблоны Jinja2

Собирать HTML строками неудобно и опасно, для этого есть шаблоны. Файлы шаблонов кладут в папку templates рядом с приложением и вызывают через render_template(), передавая переменные именованными аргументами.

from flask import render_template

@app.route("/list")
def note_list():
    return render_template("notes.html", title="Заметки", notes=NOTES)
<!-- templates/notes.html -->
{% extends "base.html" %}
{% block content %}
  <h1>{{ title }}</h1>
  <ul>
  {% for id, text in notes.items() %}
    <li><a href="{{ url_for('post', post_id=id) }}">{{ text }}</a></li>
  {% else %}
    <li>Заметок нет</li>
  {% endfor %}
  </ul>
{% endblock %}

Двойные фигурные скобки выводят значение, конструкции {% %} задают логику: циклы, условия, наследование. Jinja2 экранирует HTML в выводимых переменных, поэтому текст от пользователя с тегом <script> отобразится как текст, а не выполнится. Наследование через extends и block позволяет держать шапку и подвал в одном базовом файле, подробнее об этом в статье про создание шаблона Flask.

Структура проекта и следующие шаги

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

project/
    app.py           # создание приложения и маршруты
    config.py        # настройки, SECRET_KEY
    templates/       # HTML-шаблоны Jinja2
    static/          # CSS, JavaScript, картинки
    instance/        # локальная база и секреты, не в git

Файлы из static подключаются в шаблоне через url_for('static', filename='style.css'). Для сессий, flash-сообщений и защиты форм приложению нужен SECRET_KEY: длинная случайная строка, которую хранят вне репозитория. В крупных проектах маршруты делят на модули с помощью Blueprint.

Дальше обычно подключают расширения:

Для рабочего сервера встроенный сервер разработки не подходит: приложение запускают через WSGI-сервер, например gunicorn или waitress, за веб-сервером nginx. Подробности есть в официальной документации Flask.

Частые вопросы

Ответы на вопросы, которые чаще всего возникают при первом знакомстве с Flask.

Почему изменения в коде не видны в браузере?

Сервер запущен без режима отладки и не перезагружается сам. Запустите его с --debug или app.run(debug=True). Если не обновляются CSS-файлы, дело в кеше браузера: обновите страницу с очисткой кеша.

Как сменить порт и открыть сайт с другого устройства?

Передайте параметры: app.run(host="0.0.0.0", port=8000) или flask --app app run --host 0.0.0.0 --port 8000. Сервер станет доступен по IP-адресу компьютера в локальной сети.

Подходит ли Flask для API?

Да, представление может просто возвращать словарь, и Flask отдаст JSON. Для больших API добавляют проверку входных данных, например через Pydantic или marshmallow.

Где хранить данные между запросами?

Глобальные переменные вроде NOTES из примеров подходят только для учебы: они пропадут при перезапуске и не работают при нескольких процессах сервера. Для данных нужна база, а для данных конкретного пользователя объект session.