Веб-разработка на Flask
Что такое Flask?
Что нам понадобится?
Установка виртуального окружения
Установка Flask
Структура папок для начала
Минимальное жизнеспособное приложение (Hello World)
Запуск первого приложения
Что такое маршрутизация (Routing)?
Добавляем новый маршрут (/about)
Динамические маршруты (Переменные в URL)
Конвертеры типов в динамических маршрутах
Конвертер path
Конвертер uuid
Обработка HTTP методов (GET, POST)
Внимание, в return стоят просто заглушки для примера
Импорт request
Шаблонизация (Templates) с Jinja2
Создаем структуру папок для шаблонов
Рендеринг первого шаблона (функция render_template())
Создаем index.html
Передача переменных в шаблон
Синтаксис Jinja2: {{ ... }}
Синтаксис Jinja2: {% ... %} (Управляющие конструкции)
Циклы в Jinja2
Наследование шаблонов (base template)
Использование наследования ({% extends %})
Включение подшаблонов ({% include %})
Работа с Формами
Маршрут для обработки формы (GET + POST)
Если все красное
Если заполнить форму и отправить – вывод в консоли spider
Проблема: Повторная отправка формы (Double Submit)
Объект request.form
Перенаправление (Redirect) и url_for
Меняем логику обработки POST:
Создаем страницу успеха
0.99M
Category: programmingprogramming

работа с flask

1. Веб-разработка на Flask

2. Что такое Flask?

• Объяснение: Микрофреймворк для веб-разработки на Python.
• Аналогия: Если большой фреймворк (как Django) — это готовый
мебельный гарнитур, то Flask — это набор инструментов и
качественных материалов (молоток, гвозди, доски), из которых
вы сами собираете мебель по своему проекту.
• Ключевые особенности:
• Простой и легкий.
• Гибкий и расширяемый (вы сами выбираете инструменты для БД,
аутентификации и т.д.).
• Имеет мощное сообщество и множество расширений.

3. Что нам понадобится?

• Установленный Python (3.6+)
• Текстовый редактор (Spider, VS Code, PyCharm и тп.)
• Терминал (Command Prompt)
• Браузер

4. Установка виртуального окружения

• Зачем? Чтобы изолировать зависимости проекта и не допустить
конфликтов версий пакетов между разными проектами.
• Аналогия: Отдельная комната для каждого проекта, где хранятся
только его собственные инструменты.

5. Установка Flask

• pip install flask
Проверяем установку:
pip list
# В списке должен быть Flask и
его зависимости

6. Структура папок для начала

• app.py
# Наш главный файл приложения

7. Минимальное жизнеспособное приложение (Hello World)

• Код в app.py:
from flask import Flask # Импортируем класс Flask
app = Flask(__name__)
# Создаем экземпляр класса. __name__ - имя текущего модуля.
@app.route('/')
# Декоратор. Говорит Flask: "на URL '/' запусти функцию below()“
def hello_world():
return 'Hello, World!’
if __name__ == '__main__’:
# Запускаем сервер, только если файл запущен напрямую
app.run(debug=True, use_reloader=False)
# debug=True включает режим отладки (автоперезагрузка, подробные ошибки)

8. Запуск первого приложения

• Запускаем app.py
Результат: В терминале увидим что-то вроде * Running on
http://127.0.0.1:5000/.
• Открываем браузер и переходим по адресу http://127.0.0.1:5000/.
• Ура! Вы должны увидеть "Hello, World!".

9. Что такое маршрутизация (Routing)?

• Объяснение: Это процесс определения, как приложение отвечает
на клиентский запрос к определенному URL (например, /, /about).
Декоратор @app.route() используется для привязки функции к
URL.

10. Добавляем новый маршрут (/about)

• Обновляем app.py:
@app.route('/about')
def about():
return 'Это страница "О нас“’
Сохраняем и перезапускаем сервер
Переходим в браузере на http://127.0.0.1:5000/about

11. Динамические маршруты (Переменные в URL)

• Зачем? Чтобы создавать страницы для разных пользователей,
товаров и т.д. по одному шаблону.
• Синтаксис: <variable_name>.
@app.route('/user/<username>’)
def show_user_profile(username):
# Функция принимает username как аргумент
return f'Пользователь: {username}'

12.

• Пример: Запрос к /user/sl вернет "Пользователь: sl".

13. Конвертеры типов в динамических маршрутах

• Можно указать тип переменной: string (по умолчанию), int, float,
path, uuid.
@app.route('/post/<int:post_id>’)
# Гарантирует, что post_id - целое число
def show_post(post_id):
return f'Пост с id #{post_id}'

14.

• Пример: /post/123 сработает, /post/abc вернет ошибку 404 (Not
Found).

15. Конвертер path

• Конвертер path похож на стандартный string, но с одним ключевым отличием: он не
игнорирует слеши (/). Обычный строковый конвертер останавливается на первом
слеше, в то время как path захватывает всю оставшуюся часть URL, включая слеши.
• Зачем это нужно?
• Это полезно, когда вам нужно работать с путями в URL, например:
Отображение вложенных страниц (/docs/section/page/subpage)
Работа с файловыми путями в URL
Создание иерархической структуры страниц

16.

@app.route('/wiki/<path:page_path>’)
def show_wiki_page(page_path):
return f'Вы запросили страницу вики: {page_path}'

17.

• Как работает:
URL: /wiki/Python/Web/Flask
Результат: page_path = 'Python/Web/Flask'
Если бы использовался string: page_path = 'Python' (только до
первого слеша)

18. Конвертер uuid

• Что это?
• Конвертер uuid проверяет, соответствует ли переданное значение формату UUID
(Universally Unique Identifier) — стандарту генерации уникальных идентификаторов.
• Зачем это нужно?
Для работы с UUID-идентификаторами в базе данных
Для обеспечения корректного формата идентификаторов
UUID часто используются в распределенных системах вместо автоинкрементных
числовых ID

19.

• Формат UUID:
• 32 шестнадцатеричные цифры, разделенные дефисами на
группы: 8-4-4-4-12
• Пример: 550e8400-e29b-41d4-a716-446655440000

20.

@app.route('/user/<uuid:user_id>’)
def show_user(user_id):
return f'Профиль пользователя с UUID: {user_id}'

21.

• Как работает:
• URL: /user/550e8400-e29b-41d4-a716-446655440000 —
сработает
• URL: /user/123 — вернет ошибку 404 (Not Found), так как не
соответствует формату UUID

22.

• Будет ошибка только если не забыли закомментировать роут
• @app.route('/user/<username>’) – если он будет первее, то
ошибки не будет так как будет срабатывать как username

23.

24. Обработка HTTP методов (GET, POST)

• GET: Используется для получения данных с сервера (открытие
страницы).
• POST: Используется для отправки данных на сервер (форма
регистрации, логина).
• По умолчанию маршруты обрабатывают только GET. Чтобы
разрешить другие, используем параметр methods:

25. Внимание, в return стоят просто заглушки для примера

@app.route('/login', methods=['GET', 'POST’])
def login():
if request.method == 'POST':
# Обрабатываем данные формы
return do_the_login() else:
# Показываем саму форму
return show_the_login_form()

26. Импорт request

• Чтобы работать с входящими данными (формами, JSON), нам
нужен объект request из Flask.
• Обновляем импорт:
from flask import Flask, request # Добавляем request

27. Шаблонизация (Templates) с Jinja2

• Проблема: Смешивать HTML и Python в return — плохая практика
(сложно читать, поддерживать, невозможно для дизайнеров).
Решение: Шаблоны. Отделяем логику (Python) от
представления (HTML).
Flask использует мощный движок шаблонов Jinja2.

28. Создаем структуру папок для шаблонов

• templates/
# Новая папка для шаблонов!
• │ └── index.html # Наш первый шаблон
• app.py

29. Рендеринг первого шаблона (функция render_template())

• Импортируем render_template.
from flask import Flask, render_template
# Добавляем импорт
app = Flask(__name__)@app.route('/’)
def index():
return render_template('index.html’)
# Рендерим шаблон index.html

30. Создаем index.html

• Код в templates/index.html
<!DOCTYPE html><html><head> <title>Мой сайт на
Flask</title></head><body> <h1>Привет от Jinja2!</h1> <p>Это
мой первый шаблон.</p></body></html>

31. Передача переменных в шаблон

• Второй аргумент render_template — переменные.
@app.route('/user/<name>’)
def user(name):
return render_template('user.html', username=name)
# Теперь в шаблоне user.html доступна переменная {{ username }}

32.

• <!DOCTYPE html><html><head> <title>Мой сайт на
Flask</title></head><body> <h1>Привет от {{username}}}</h1>
<p>Это мой первый шаблон.</p></body></html>

33. Синтаксис Jinja2: {{ ... }}

• {{ переменная }} — вывод значения переменной.
• Код в templates/user.html:
<h1>Привет, {{ username }}!</h1>

34. Синтаксис Jinja2: {% ... %} (Управляющие конструкции)

• {% ... %} — для операторов (циклы, условия).
• Пример условия:
{% if username == 'admin' %}
<h1>Привет, Администратор!</h1>
{% else %} <h1>Привет, {{ username }}!</h1>{% endif %}

35. Циклы в Jinja2

• Пример цикла (передача списка из Python):
@app.route('/posts')def posts():
posts_list = ['Пост 1', 'Пост 2', 'Пост 3']
return render_template('posts.html', posts=posts_list)

36.

• <ul>{% for post in posts %} <li>{{ post }}</li>{% endfor %}</ul>

37. Наследование шаблонов (base template)

• Проблема: На всех страницах повторяется один и тот же HTML
(header, меню, footer).
• Решение: Создать базовый шаблон, который будут наследовать
все остальные.
• Создаем templates/base.html:

38.

• <!DOCTYPE html><html><head> <title>{% block title %}Мой сайт{%
endblock %}</title></head><body> <nav>... навигация ...</nav>
<main>
{% block content %}
{% endblock %} </main>
<footer>... подвал ...</footer></body></html>

39. Использование наследования ({% extends %})

• Теперь index.html можно переписать:
• {% extends "base.html" %}{% block title %}Главная страница{%
endblock %}{% block content %} <h1>Привет от Jinja2!</h1> <p>Это
мой первый шаблон.</p>{% endblock %}

40. Включение подшаблонов ({% include %})

• Для повторяющихся кусков кода (виджеты, элементы меню).
• Создаем templates/_navbar.html:
• <nav><a href="/">Главная</a> | <a href="/about">О нас</a></nav>

41.

• Вставляем в base.html:
<body> {% include '_navbar.html' %} <main>... </main></body>

42. Работа с Формами

• Создаем templates/contact.html
{% extends 'base.html' %}{% block content %}<h1>Свяжитесь с
нами</h1><form method="POST"> <label>Имя:</label> <input
type="text" name="username" required> <br>
<label>Email:</label> <input type="email" name="email" required>
<br> <label>Сообщение:</label> <textarea
name="message"></textarea> <br> <input type="submit"
value="Отправить"></form>{% endblock %}

43. Маршрут для обработки формы (GET + POST)

@app.route('/contact', methods=['GET', 'POST’])
def contact():
if request.method == 'POST':
# Получаем данные из формы
username = request.form['username’]
email = request.form['email']
message = request.form['message']
# Здесь можно сохранить в БД или отправить по email
print(f"Сообщение от {username} ({email}): {message}")
return f"Спасибо, {username}, ваше сообщение отправлено!"
# Если метод GET, просто показываем форму
return render_template('contact.html')

44. Если все красное

• значит забыли импорт
from flask import Flask, render_template, request # Добавляем
импорт

45.

46. Если заполнить форму и отправить – вывод в консоли spider

• ImmutableMultiDict([('username', 'ljlkjkj'), ('email',
'ljkjlk@sdfsfsdfsdfsdf'), ('message', 'rereerere')])
• Сообщение от ljlkjkj (ljkjlk@sdfsfsdfsdfsdf): rereerere

47. Проблема: Повторная отправка формы (Double Submit)

• Проблема: После отправки формы и обновления страницы
браузер пытается отправить данные снова.
• Решение: Перенаправление (Redirect) после успешной
обработки POST-запроса.

48. Объект request.form

• request.form — это словарь, который содержит все данные,
отправленные через форму (с полей input, textarea и т.д.).
Обращение к полю: request.form['field_name'].

49. Перенаправление (Redirect) и url_for

• from flask import Flask, render_template, request, redirect, url_for

50. Меняем логику обработки POST:

• if request.method == 'POST':
username = request.form['username']
# ... обработка ...
return redirect(url_for('success', username=username))
# Перенаправляем

51. Создаем страницу успеха

• @app.route('/success/<username>’)
def success(username):
return render_template('success.html', username=username)
English     Русский Rules