Flask

Сайт: Информатикс
Курс: 2086 9М Информатика
Книга: Flask
Напечатано:: Гость
Дата: Суббота, 14 Март 2026, 08:06

1. Hello world!

Hello world в flask:

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
     return "<p>Hello, World!</p>"

app.run()

После этого зайдите в браузере по адресу localhost:5000/.

2. Маршруты

Для того, чтобы у вашего сайта была больше, чем одна страница, следует воспользоваться

@app.route(*путь*)

и после этой строчки написать функцию, которая будет возвращать страницу по этому пути.

К примеру, чтобы показать описание сайта, можно сделать отдельную страницу по адресу "localhost:5000/about" :
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
     return 'Hello page!'

@app.route("/about")
def about_page():
    return 'Its about page!'

app.run()

Также можно добавить переменные в путь, к примеру:

@app.route(/user/<username>) # синтаксис <*имя переменной*> позволяет задать имя переменной
def user_page(username): #обратите внимание, что у функции появился параметр
    #сюда можно добавить проверку на то, что пользователь существует
    return 'Its page of ' + username

Тогда при обращении по адресу
localhost:5000/user/Abrakadabra
мы увидим
Its page of Abrakadabra

Разрешается использовать сразу несколько переменных в пути, а также задавать, какого типа будет переменная:

@app.route(/user/<string:username>/post/<int:post>)
def user_page(username): #обратите внимание, что у функции появился параметр
    #сюда можно добавить проверку на то, что пользователь существует, и пост с этим номером существует
    return 'Its page of (string)' + username + ' and post with number ' + post

Таким образом гарантируется, что post будет именно числом. Иначе сайт выдаст ошибку, что такого адреса в сайте нет.  При обращении по адресу
localhost:5000/user/Abrakadabra/post/2086
мы увидим
Its page of Abrakadabra and post with number 2086

Все возможные типы:

string

(по умолчанию) принимает любую строку без слэшей ("/")

int

принимает любые положительные целые числа

float

принимает любые положительные числа с точкой ("3.14")

path

как string, но ещё и принимает слэши



3. Страницы

Во всех примерах из первых двух глав в качестве "страниц" использовались строчки. Flask позволяет возвращать функциями настоящие страницы с помощью функции render_template(*название файла*, *переменные для шаблона*).

Для того, чтобы воспользоваться этой функцией, нужно сделать следующее:
а) Добавить эту функцию import'ом
б) Создать шаблон, и добавить её в папку templates (создать папку в месте запуска .py программы, если её нет)
в) В return функции написать render_template(*название файла*)

from flask import Flask, render_template

app = Flask(__name__)

@app.route("/")
def hello_world():
     return render_template('hello_world.html')

app.run()

В шаблонах можно писать особый "шаблоновский" код, пока что мы его затрагивать не будет, но можно найти документацию и почитать, если Вам интересно уже сейчас https://jinja.palletsprojects.com/en/2.11.x/templates/


4. Формы

Ответ по ссылке, не единственный способ взаимодействовать с пользователем.
К примеру, пользователь может хотеть отправить данные для регистрации или входа. Для этого существует два вида запросов: GET и POST. GET запросы нужны для того, чтобы получить страницы (собственно GET запрос используется, когда вы заходите на localhost:5000/, yandex.ru/ и другие сайты), POST запросы нужны для того, чтобы передать какую-то информацию на сервер.
Для того, чтобы обрабатывать POST запросы, нужно import'нуть request и, создавая функции для адресов, сделать следующее:

from flask import Flask, request

app = Flask(__name__)

@app.route("/", methods=['GET', 'POST']) #добавили методы
def hello_world():
    if request.method == 'GET':
        return 'Hello GET world!'
    else:
        return 'Hello POST world!'

app.run()

Будет закономерным вопрос, как пользователь может отправить этот самый POST запрос. Один из способов этой сделать: формы в HTML. Создадим следующую страницу:

<!DOCTYPE html>
<html>
<head>
<title>
Привет мир!
</title>
</head>
<body><form method="post">
<p>Логин:</p>
<input type="text" id="username" name="username" required>
<p>Пароль:</p>
<input type="password" id="password" name="password" required>
<button type="submit">Войти</button>
</form>
</body>
</html>

С её помощью можно ввести "username" и "password", после чего их отправить. Для того, чтобы их обработать, нужно воспользоваться request.form[*название поля*].

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route("/", methods=['GET', 'POST']) #добавили методы
def hello_world():
    if request.method == 'GET':
        return render_template('hellow_world.html')
    else:
        print(request.form['username'])
        print(request.form['password'])
        return 'Hello POST world!'

app.run()


5. Сессия

Для взаимодействия между разными GET запросами используется session, с помощью которой Вы можете хранить информацию для каждого пользователя отдельно. Пример использования:

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

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
     if 'username' in session: # проверка на наличие
          return f'Logged in as {session["username"]}'
     return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
     if request.method == 'POST':
          session['username'] = request.form['username'] # назначить значение
          return redirect(url_for('index')) # функция redirect перенаправляет по ссылке, url_for генерирует ссылку по названию функции!!!
     return '''
     <form method="post">
     <p><input type=text name=username>
     <p><input type=submit value=Login>
     </form>
     ''' # явно прописали страницу

@app.route('/logout')
def logout():
     session.pop('username', None)
     return redirect(url_for('index'))

app.run()

6. Подробнее о шаблонах 1

Шаблоны позволяют модифицировать html код так, чтобы была "давать на вход" параметры.
К примеру, Вы хотите, чтобы страница в некотором месте писала номер посещения. Тогда с помощью шаблона можно дать возможность серверу указать номер посещения при обработке шаблона, и таким образом страница будет каждый раз отличаться номером посещения.

Синтаксис внутри самого шаблона: (звёздочки указаны для удобства восприятия, писать их в шаблоне не нужно)

{{ *название переменной* }} # напечатать содержимое переменной
{% *некоторое выражение* %} # используется для if, for и прочих конструкций
{# *комметарий* #}          # используется для комментариев

Пример:

<!DOCTYPE html>
<html>
<head>
<title>
Начальная страница!
</title>
</head>
<body>
Я {{ content1 }}. <br>
Вот содержимое content2: <br>
{{ content2|safe }} <br>
А вот содержимое массива data: <br>
{% for element in data %}
{{ element }} <br>
{% endfor %}
</body>
</html>

Для того, чтобы задать значение переменной (и в принципе воспользоваться шаблоном), нужно воспользоваться функцией render_template. Ранее мы использовали её для того, чтобы возвращать HTML страницы, но подав в render_template дополнительные параметры мы сможем воспользоваться всем функционалом шаблонов. 
Пример python кода:

from flask import Flask, render_template, url_for

app = Flask(__name__)

@app.route("/")
def index():
  return render_template('index.html', content1='Alexey Mischenko', content2='<button>БЕСПОЛЕЗНАЯ КНОПКА</button>', data=[1,2,3])

app.run()

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

Обратите внимание, что content2 окажется именно кнопкой, т.к. в шаблоне прописан "фильтр" safe. Если его убрать, то будет написано <button>, и никакой кнопки не будет.

7. Подробнее о шаблонах 2 - наследование

В шаблонах также можно создавать "родительские" шаблоны, и наследовать от них другие шаблоны. Это значит, что можно использовать один и тот же паттерн HTML кода (и не только!) в нескольких шаблонах, причём изменив родительский шаблон изменятся все шаблоны, в которые было сделано наследование. Рассмотрим синтаксис:

Родитель

<!DOCTYPE html>
<html>
<head>
<title>
{% block title %} Начальная страница! {% endblock %}
</title>
</head>
<body>
Некоторая общая часть <br>
<a href="{{ link_start }}">Ссылка на главную страницу</a> <br>
<a href="{{ link_start }}number/1">1</a> <br>
{% block content %}{% endblock %}<br>
{% block content2 %}Здесь контент:<br>{% endblock %}
</body>
</html>

Наследник (Ребёнок)

{% extends "parent.html" %}
{% block title %}Другое название{% endblock %}
{% block content %}<button>КНОПКА!</button>{% endblock %}
{% block content2 %} {{ super() }} <button>ДРУГАЯ КНОПКА!</button> {% endblock %}

В родителе прописаны "блоки". Как можно видеть, в наследуемых шаблонах можно обращаться к этим блокам и перезаписывать их значения. Если вам нужно обратиться к значению блока в родителе, пользуйтесь {{ super() }}.

Python код для того, чтобы проверить, как это выглядит:

from flask import Flask, render_template, url_for
app = Flask(__name__)

link_start = '127.0.0.1:5000'

@app.route("/parent")
def parent():    
    link_start = url_for('index')    
    return render_template('parent.html', link_start=link_start)

@app.route("/child")
def child():    
    link_start = url_for('index')    
    return render_template('child.html', link_start=link_start)

app.run()