Быстрый старт
Желаете начать работу? Эта страница предоставляет хорошее введение в Flask. Предполагается, что у вас уже установлен Flask. Если нет, перейдите к разделу Установка.
Минимальное приложение
Минимальное приложение Flask выглядит примерно так:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
Что делает этот код?
- Сначала мы импортировали класс
Flask. Экземпляр этого класса будет нашим WSGI-приложением. - Далее мы создаем экземпляр этого класса. Первым аргументом является имя модуля или пакета приложения. Если вы используете один модуль (как в этом примере), вы должны использовать
__name__, потому что в зависимости от того, как оно запущено (как приложение или импортирован как модуль), имя будет отличаться ('__main__'против фактического имени импорта). Это необходимо, чтобы Flask знал, где искать шаблоны, статические файлы и т. д. Дополнительную информацию можно найти в документацииFlask. - Затем мы используем декоратор
route(), чтобы указать Flask, какой URL должен вызывать нашу функцию. - Функции присваивается имя, которое также используется для генерации URL для этой конкретной функции, и она возвращает сообщение, которое мы хотим отобразить в браузере пользователя.
Сохраните его как hello.py или что-то подобное. Убедитесь, что вы не назвали своё приложение flask.py , так как это может вызвать конфликт с самим Flask.
Чтобы запустить приложение, вы можете использовать команду flask или переключатель Python -m с Flask. Прежде чем вы это сделаете, вам нужно указать терминалу приложение, с которым работать, экспортировав переменную окружения FLASK_APP.
$ export FLASK_APP=hello.py $ flask run * Running on http://127.0.0.1:5000/
Если вы работаете в Windows, вам нужно использовать set вместо export.
В качестве альтернативы вы можете использовать python -m flask:
$ export FLASK_APP=hello.py $ python -m flask run * Running on http://127.0.0.1:5000/
Это запускает очень простой встроенный сервер, который достаточно хорош для тестирования, но, вероятно, не то, что вам нужно для производства. С вариантами развертывания ознакомьтесь в разделе Варианты развертывания.
Теперь перейдите по адресу http://127.0.0.1:5000/, и вы должны увидеть приветствие «hello world».
Внешне видимый сервер
Если вы запустите сервер, вы заметите, что к нему можно получить доступ только с вашего компьютера, а не с любого другого в сети. Это значение по умолчанию, так как в режиме отладки пользователь приложения может выполнить произвольный код Python на вашем компьютере.
Если отладчик отключен или вы доверяете пользователям в вашей сети, вы можете сделать сервер общедоступным, просто добавив --host=0.0.0.0 в командную строку:
flask run --host=0.0.0.0
Это сообщает вашей операционной системе прослушивать все общедоступные IP-адреса.
Что делать, если сервер не запускается
Если команда python -m flask завершается ошибкой или flask отсутствует, причин этому может быть несколько. В первую очередь необходимо изучить сообщение об ошибке.
Старая версия Flask
В версиях Flask, предшествующих 0.11, существовали иные способы запуска приложения. Короче говоря, команда flask не существовала, как и python -m flask. В этом случае у вас есть два варианта: обновить до более новой версии Flask или изучить документацию Сервер разработки, чтобы узнать альтернативный метод запуска сервера.
Неверное имя импорта
Переменная среды FLASK_APP — это имя модуля, который нужно импортировать при выполнении flask run. Если имя модуля указано неверно, при запуске возникнет ошибка импорта (или если отладка включена, когда вы переходите к приложению). Она сообщит вам, что пыталось импортировать и почему не удалось.
Самая распространённая причина — опечатка или отсутствие объекта app.
Режим отладки
(Хотите просто регистрировать ошибки и трассировки стека? См. Ошибки приложения)
Скрипт flask удобен для запуска локального сервера разработки, но после каждого изменения кода его нужно перезапускать вручную. Это не очень удобно, и Flask может сделать лучше. Если вы включите поддержку отладки, сервер будет перезагружаться при изменении кода, а также предоставит вам полезный отладчик, если что-то пойдёт не так.
Для включения режима отладки можно экспортировать переменную окружения FLASK_DEBUG перед запуском сервера:
$ export FLASK_DEBUG=1 $ flask run
(В Windows нужно использовать set вместо export).
Это делает следующее:
- активирует отладчик
- активирует автоматическую перезагрузку
- включает режим отладки в приложении Flask.
Есть и другие параметры, которые объяснены в документации Сервер разработки.
Внимание
Несмотря на то, что интерактивный отладчик не работает в средах форкинга (что делает его практически непригодным для использования на серверах производства), он всё ещё позволяет выполнять произвольный код. Это представляет собой серьёзную угрозу безопасности, поэтому его никогда нельзя использовать на производственных машинах.
Скриншот отладчика в действии:
Ищете другой отладчик? См. Работа с отладчиками.
Маршрутизация
Современные веб-приложения имеют красивые URL. Это помогает пользователям запоминать URL, что особенно удобно для приложений, которые используются с мобильных устройств с медленным подключением к сети. Если пользователь может напрямую перейти на нужную страницу, не заходя на главную, это увеличивает вероятность, что ему понравится страница, и он вернётся в следующий раз.
Как вы видели выше, декоратор route() используется для привязки функции к URL. Вот несколько основных примеров:
@app.route('/')
def index():
return 'Index Page'
@app.route('/hello')
def hello():
return 'Hello, World'
Но есть больше! Вы можете сделать динамичными определённые части URL и прикрепить к функции несколько правил.
Правила переменных
Чтобы добавить переменные части в URL, вы можете отметить эти специальные разделы как <variable_name>. Затем такая часть передается в вашу функцию в качестве ключевого аргумента. Необязательно использовать преобразователь, указав правило с <converter:variable_name>. Вот несколько хороших примеров:
@app.route('/user/<username>')
def show_user_profile(username):
# show the user profile for that user
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# show the post with the given id, the id is an integer
return 'Post %d' % post_id
Существуют следующие преобразователи:
| принимает любой текст без слэша (по умолчанию) |
| принимает целые числа |
| подобно |
| подобно по умолчанию, но также принимает слэши |
| сопоставляет один из предоставленных элементов |
| принимает строки UUID |
Уникальные URL / Поведение перенаправления
Правила URL Flask основаны на модуле маршрутизации Werkzeug. Идея этого модуля состоит в том, чтобы гарантировать красивые и уникальные URL, основываясь на прецедентах, установленных Apache и более ранними HTTP-серверами.
Рассмотрим эти два правила:
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
Хотя они выглядят довольно похожими, они отличаются использованием конечного слэша в определении URL. В первом случае канонический URL для конечной точки projects имеет конечный слэш. В этом смысле он похож на папку в файловой системе. Доступ к нему без конечного слэша заставит Flask перенаправить на канонический URL с конечным слэшем.
Во втором случае, однако, URL определен без конечного слэша, как путь к файлу в системах типа UNIX. Доступ к URL с конечным слэшем приведет к ошибке 404 «Не найдено».
Это поведение позволяет относительным URL продолжать работать, даже если конечный слэш опущен, что соответствует тому, как работают Apache и другие серверы. Кроме того, URL останутся уникальными, что помогает поисковым системам избежать индексирования одной и той же страницы дважды.
Генерация URL
Если Flask может сопоставлять URL, может ли он также их генерировать? Конечно, может. Чтобы создать URL для определенной функции, можно использовать функцию url_for(). Она принимает имя функции в качестве первого аргумента и несколько ключевых аргументов, каждый из которых соответствует переменной части правила URL. Неизвестные переменные части добавляются к URL в качестве параметров запроса. Вот несколько примеров:
>>> from flask import Flask, url_for
>>> app = Flask(__name__)
>>> @app.route('/')
... def index(): pass
...
>>> @app.route('/login')
... def login(): pass
...
>>> @app.route('/user/<username>')
... def profile(username): pass
...
>>> with app.test_request_context():
... print url_for('index')
... print url_for('login')
... print url_for('login', next='/')
... print url_for('profile', username='John Doe')
...
/
/login
/login?next=/
/user/John%20Doe
(Здесь также используется метод test_request_context(), объясненный ниже. Он говорит Flask вести себя так, как будто он обрабатывает запрос, даже если мы взаимодействуем с ним через оболочку Python. Посмотрите объяснение ниже. Локальные переменные контекста).
Почему бы вам не создавать URL с помощью функции обратного преобразования URL url_for(), а не вводить их напрямую в шаблоны? Существует три веских причины:
- Обратное преобразование часто более описательно, чем непосредственный ввод URL. Более того, оно позволяет вам изменить URL единым действием, без необходимости помнить о том, чтобы изменить URL повсюду.
- Генерация URL будет обрабатывать экранирование специальных символов и данных Unicode прозрачно, поэтому вам не нужно беспокоиться о них.
- Если ваше приложение размещено вне корня URL — скажем, в
/myapplicationвместо/—url_for()обработает это должным образом.
HTTP-методы
HTTP (протокол, используемый веб-приложениями) знает разные методы доступа к URL-адресам. По умолчанию маршрут отвечает только на GET запросы, но это можно изменить, передав аргумент methods декоратору route(). Вот несколько примеров:
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
do_the_login()
else:
show_the_login_form()
Если GET присутствует, HEAD будет автоматически добавлен. Вам не нужно этим заниматься. Он также гарантирует, что HEAD запросы обрабатываются так, как требует HTTP RFC (документ, описывающий протокол HTTP), поэтому вы можете полностью игнорировать эту часть спецификации HTTP. Точно так же, начиная с Flask 0.6, OPTIONS реализуется автоматически.
Вы не знаете, что такое HTTP-метод? Не беспокойтесь, вот краткое введение в HTTP-методы и почему они важны:
HTTP-метод (также часто называемый «глаголом») сообщает серверу, что клиент хочет сделать с запрошенной страницей. Следующие методы очень распространены:
-
GET -
Браузер сообщает серверу просто получить информацию, хранящуюся на этой странице, и отправить её. Это, вероятно, самый распространённый метод.
-
HEAD -
Браузер сообщает серверу получить информацию, но он интересуется только заголовками, а не содержимым страницы. Приложение должно обработать это так, как если бы был получен запрос
GET, но не передавать фактическое содержимое. В Flask вам не нужно этим заниматься, поскольку базовая библиотека Werkzeug обрабатывает это за вас. -
POST -
Браузер сообщает серверу, что хочет отправить некоторую новую информацию по этому URL-адресу и что сервер должен обеспечить хранение данных только один раз. Именно так обычно HTML-формы передают данные на сервер.
-
PUT -
Аналогично
POST, но сервер может триггернуть процедуру хранения несколько раз, перезаписывая старые значения более одного раза. Теперь вы можете спросить, почему это полезно, но есть несколько веских причин для этого. Представьте, что соединение разорвано во время передачи: в этом случае система между браузером и сервером может безопасно получить запрос во второй раз, не сломав ничего. СPOSTэто было бы невозможно, потому что он должен срабатывать только один раз. -
DELETE -
Удалить информацию по указанному расположению.
-
OPTIONS -
Предоставляет быстрый способ для клиента выяснить, какие методы поддерживаются этим URL. Начиная с Flask 0.6, это реализуется автоматически.
Теперь интересная часть заключается в том, что в HTML4 и XHTML1 единственными методами, которые форма может отправлять на сервер, являются GET и POST. Но с JavaScript и будущими стандартами HTML вы можете использовать и другие методы. Кроме того, HTTP стал довольно популярным в последнее время, и браузеры больше не являются единственными клиентами, использующими HTTP. Например, многие системы управления версиями используют его.
Статические файлы
Динамические веб-приложения также нуждаются в статических файлах. Обычно оттуда берутся файлы CSS и JavaScript. В идеале ваш веб-сервер настроен на их предоставление, но во время разработки Flask может это сделать. Просто создайте папку под названием static в вашем пакете или рядом с вашим модулем, и она будет доступна по адресу /static в приложении.
Для генерации URL статических файлов используйте специальное имя конечной точки 'static':
url_for('static', filename='style.css')
Файл должен храниться в файловой системе как static/style.css.
Отображение шаблонов
Генерация HTML изнутри Python не является приятной задачей и на самом деле довольно сложной, так как вам нужно самостоятельно выполнять HTML-экранирование, чтобы обеспечить безопасность приложения. По этой причине Flask автоматически настраивает движок шаблонов Jinja2 для вас.
Чтобы отобразить шаблон, вы можете использовать метод render_template(). Вам нужно только указать имя шаблона и переменные, которые вы хотите передать в движок шаблонов, как ключевые аргументы. Вот простой пример отображения шаблона:
from flask import render_template
@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
Flask будет искать шаблоны в папке templates. Итак, если ваше приложение — это модуль, эта папка находится рядом с этим модулем, если это пакет, то она находится внутри пакета:
Случай 1: модуль:
/application.py
/templates
/hello.html
Случай 2: пакет:
/application
/__init__.py
/templates
/hello.html
Для шаблонов вы можете использовать всю мощь шаблонов Jinja2. Подробнее ознакомьтесь с официальной документацией по шаблонам Jinja2.
Вот пример шаблона:
<!doctype html>
<title>Hello from Flask</title>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
Внутри шаблонов также доступны объекты request, session и g 1, а также функция get_flashed_messages().
Шаблоны особенно полезны, если используется наследование. Если вы хотите узнать, как это работает, обратитесь к документации шаблона Template Inheritance. В основе наследования шаблонов лежит возможность сохранения определенных элементов на каждой странице (например, заголовка, навигации и подвала).
Автоматическое экранирование включено, поэтому, если name содержит HTML, он будет автоматически экранирован. Если вы можете доверять переменной и знаете, что она будет безопасным HTML (например, потому что она получена из модуля, который преобразует разметку wiki в HTML), вы можете пометить её как безопасную, используя класс Markup или используя фильтр |safe в шаблоне. Обратитесь к документации Jinja 2 для получения дополнительных примеров.
Вот базовое введение в работу класса Markup:
>>> from flask import Markup
>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup(u'<strong>Hello <blink>hacker</blink>!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup(u'<blink>hacker</blink>')
>>> Markup('<em>Marked up</em> » HTML').striptags()
u'Marked up \xbb HTML'
Изменения
Изменено в версии 0.5: Автоматическое экранирование больше не включено для всех шаблонов. Следующие расширения шаблонов вызывают автоматическое экранирование: .html, .htm, .xml, .xhtml. Для шаблонов, загруженных из строки, автоматическое экранирование отключено.
-
1 -
Не знаете, что такое объект
g? Это то, в котором вы можете хранить информацию для своих нужд. Посмотрите документацию по этому объекту (g) и Использование SQLite 3 с Flask для получения дополнительной информации.
Доступ к данным запроса
Для веб-приложений крайне важно реагировать на данные, которые клиент отправляет серверу. В Flask эта информация предоставляется глобальным объектом request. Если у вас есть некоторый опыт работы с Python, вы можете задаться вопросом, как этот объект может быть глобальным и как Flask всё ещё может быть потокобезопасным. Ответ — контекстные локальные переменные:
Контекстные локальные переменные
Справочная информация
Если вы хотите понять, как это работает и как вы можете реализовать тесты с контекстными локальными переменными, прочитайте этот раздел, иначе просто пропустите его.
Определенные объекты в Flask являются глобальными объектами, но не обычного типа. Эти объекты фактически являются прокси к объектам, которые локальны для конкретного контекста. Как многословно.
Представьте, что контекст — это обрабатывающий поток. Поступает запрос, и веб-сервер решает запустить новый поток (или что-то другое, базовый объект способен обрабатывать системы параллельности, отличные от потоков). Когда Flask начинает свою внутреннюю обработку запроса, он определяет, что текущий поток является активным контекстом, и связывает текущее приложение и среды WSGI с этим контекстом (потоком). Он делает это разумно, чтобы одно приложение могло вызывать другое приложение без сбоев.
Что это значит для вас? В основном вы можете полностью игнорировать это, если не занимаетесь чем-то вроде тестирования модулей. Вы заметите, что код, который зависит от объекта запроса, внезапно перестанет работать, поскольку объекта запроса нет. Решение — создать объект запроса самостоятельно и привязать его к контексту. Самое простое решение для тестирования модулей — использовать контекстный менеджер test_request_context(). В сочетании с инструкцией with она свяжет тестовый запрос, чтобы вы могли с ним взаимодействовать. Вот пример:
from flask import request
with app.test_request_context('/hello', method='POST'):
# now you can do something with the request until the
# end of the with block, such as basic assertions:
assert request.path == '/hello'
assert request.method == 'POST'
Другой вариант — передать всю среду WSGI методу request_context():
from flask import request
with app.request_context(environ):
assert request.method == 'POST'
Объект запроса
Объект запроса документирован в разделе API, и мы не будем подробно его рассматривать здесь (см. request). Вот краткий обзор некоторых наиболее распространенных операций. Прежде всего, вам нужно импортировать его из модуля flask:
from flask import request
Текущий метод запроса доступен с помощью атрибута method. Для доступа к данным формы (данным, переданным в запросе POST или PUT) вы можете использовать атрибут form Вот полный пример двух упомянутых выше атрибутов:
@app.route('/login', methods=['POST', 'GET'])
def login():
error = None
if request.method == 'POST':
if valid_login(request.form['username'],
request.form['password']):
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
Что произойдёт, если ключ не существует в атрибуте form? В этом случае будет поднято исключение KeyError. Вы можете перехватить его как стандартное исключение KeyError, но если этого не сделать, вместо этого будет показана страница ошибки HTTP 400 Bad Request. Поэтому во многих ситуациях вам не придётся сталкиваться с этой проблемой.
Для доступа к параметрам, переданным в URL (?key=value), вы можете использовать атрибут args.
searchword = request.args.get('key', '')
Мы рекомендуем получать доступ к параметрам URL с помощью get или перехватывая исключение KeyError, потому что пользователи могут изменять URL, и в этом случае показ страницы ошибки 400 Bad Request будет неудобным.
Полный список методов и атрибутов объекта запроса можно найти в документации request.
Загрузка файлов
Вы можете легко обрабатывать загруженные файлы с помощью Flask. Просто убедитесь, что не забыли установить атрибут enctype="multipart/form-data" в вашей HTML-форме, иначе браузер не передаст файлы вообще.
Загруженные файлы хранятся в памяти или во временном месте на файловой системе. Вы можете получить доступ к этим файлам, посмотрев на атрибут files объекта запроса. Каждый загруженный файл хранится в этом словаре. Он ведет себя как стандартный объект Python file, но также имеет метод save(), который позволяет сохранить этот файл на файловой системе сервера. Вот простой пример, показывающий, как это работает:
from flask import request
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/uploaded_file.txt')
...
Если вы хотите узнать, как файл был назван на клиенте до загрузки в ваше приложение, вы можете получить доступ к атрибуту filename. Однако имейте в виду, что это значение может быть поддельным, поэтому никогда не доверяйте ему. Если вы хотите использовать имя файла клиента для сохранения файла на сервере, передайте его через функцию secure_filename(), предоставляемую Werkzeug:
from flask import request
from werkzeug.utils import secure_filename
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
if request.method == 'POST':
f = request.files['the_file']
f.save('/var/www/uploads/' + secure_filename(f.filename))
...
Для получения дополнительных примеров, ознакомьтесь с шаблоном Загрузка файлов.
Куки
Для доступа к куки вы можете использовать атрибут cookies. Для установки куки вы можете использовать метод set_cookie объектов ответа. Атрибут cookies объектов запроса — это словарь со всеми куки, переданными клиентом. Если вы хотите использовать сессии, не используйте куки напрямую, а вместо этого используйте сессии в Flask, которые добавляют дополнительную безопасность на основе куки.
Чтение куки:
from flask import request
@app.route('/')
def index():
username = request.cookies.get('username')
# use cookies.get(key) instead of cookies[key] to not get a
# KeyError if the cookie is missing.
Сохранение куки:
from flask import make_response
@app.route('/')
def index():
resp = make_response(render_template(...))
resp.set_cookie('username', 'the username')
return resp
Обратите внимание, что куки устанавливаются на объектах ответа. Поскольку вы обычно просто возвращаете строки из функций представления Flask, Flask преобразует их в объекты ответа для вас. Если вы явно хотите это сделать, вы можете использовать функцию make_response() и затем изменить её.
Иногда вам может потребоваться установить куки в момент, когда объект ответа ещё не существует. Это возможно с помощью шаблона Отложенные обратные вызовы запроса.
Также см. О ответах.
Перенаправления и ошибки
Для перенаправления пользователя на другой конечный пункт используйте функцию redirect(); для прерывания запроса с ошибкой используйте функцию abort():
from flask import abort, redirect, url_for
@app.route('/')
def index():
return redirect(url_for('login'))
@app.route('/login')
def login():
abort(401)
this_is_never_executed()
Это довольно бесполезный пример, поскольку пользователь будет перенаправлен с главной страницы на страницу, к которой у него нет доступа (401 означает отказ в доступе), но он демонстрирует, как это работает.
По умолчанию для каждой кода ошибки отображается черно-белая страница ошибки. Если вы хотите настроить страницу ошибки, вы можете использовать декоратор errorhandler():
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template('page_not_found.html'), 404
Обратите внимание на 404 после вызова render_template(). Это сообщает Flask, что код состояния этой страницы должен быть 404, что означает «не найдено». По умолчанию предполагается 200, что означает: всё прошло хорошо.
Дополнительную информацию см. в разделе Обработчики ошибок.
О ответах
Значение, возвращаемое функцией представления, автоматически преобразуется в объект ответа. Если возвращаемое значение — строка, оно преобразуется в объект ответа со строкой в качестве тела ответа, кодом состояния 200 OK и MIME-типом text/html. Логика, которую Flask использует для преобразования возвращаемых значений в объекты ответа, следующая:
- Если возвращается объект ответа нужного типа, он возвращается из представления напрямую.
- Если это строка, создается объект ответа с этими данными и параметрами по умолчанию.
- Если возвращается кортеж, элементы кортежа могут предоставлять дополнительную информацию. Такие кортежи должны быть в форме
(response, status, headers)или(response, headers), где по крайней мере один элемент должен быть в кортеже. Значениеstatusпереопределит код состояния, аheadersможет быть списком или словарем дополнительных значений заголовка. - Если ни один из этих вариантов не подходит, Flask предположит, что возвращаемое значение является допустимым приложением WSGI, и преобразует его в объект ответа.
Если вы хотите получить доступ к объекту результата ответа внутри представления, вы можете использовать функцию make_response().
Представьте, что у вас есть представление такого вида:
@app.errorhandler(404)
def not_found(error):
return render_template('error.html'), 404
Вам нужно только обернуть выражение возврата функцией make_response() и получить объект ответа, чтобы изменить его, а затем вернуть его:
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template('error.html'), 404)
resp.headers['X-Something'] = 'A value'
return resp
Сессии
Помимо объекта запроса, есть также второй объект, называемый session, который позволяет хранить информацию, специфичную для пользователя, от одного запроса к другому. Это реализуется поверх куки и подписывается криптографически. Это означает, что пользователь может посмотреть содержимое вашего куки, но не может его изменить, если он не знает секретный ключ, используемый для подписи.
Для использования сессий необходимо установить секретный ключ. Вот как работают сессии:
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
@app.route('/')
def index():
if 'username' in session:
return 'Logged in as %s' % escape(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'))
return '''
<form method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
'''
@app.route('/logout')
def logout():
# remove the username from the session if it's there
session.pop('username', None)
return redirect(url_for('index'))
# set the secret key. keep this really secret:
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
Упомянутая здесь функция escape() выполняет экранирование для вас, если вы не используете движок шаблонов (как в этом примере).
Как сгенерировать хорошие секретные ключи
Проблема с random заключается в том, что трудно судить, что действительно случайным. А секретный ключ должен быть максимально случайным. Ваша операционная система имеет способы генерации довольно случайных данных на основе криптографического генератора случайных чисел, который может быть использован для получения такого ключа:
>>> import os
>>> os.urandom(24)
'\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8'
Just take that thing and copy/paste it into your code and you're done.
Примечание о сессиях на основе куки: Flask будет брать значения, которые вы помещаете в объект сессии, и сериализовать их в куки. Если вы обнаруживаете, что некоторые значения не сохраняются между запросами, куки действительно включены, и вы не получаете ясного сообщения об ошибке, проверьте размер куки в ответах ваших страниц по сравнению с размером, поддерживаемым веб-браузерами.
Помимо сессий по умолчанию на клиентской стороне, если вы хотите обрабатывать сессии на стороне сервера, существуют несколько расширений Flask, которые поддерживают это.
Вывод сообщений
Хорошие приложения и пользовательские интерфейсы основаны на обратной связи. Если пользователь не получает достаточной обратной связи, он, скорее всего, возненавидит приложение. Flask предоставляет очень простой способ предоставления пользователю обратной связи с помощью системы вывода сообщений. Система вывода сообщений в основном позволяет записывать сообщение в конце запроса и получать к нему доступ в следующем (и только в следующем) запросе. Обычно это сочетается с шаблоном макета для отображения сообщения.
Для вывода сообщения используйте метод flash(), чтобы получить доступ к сообщениям, вы можете использовать get_flashed_messages(), который также доступен в шаблонах. Обратитесь к Шаблону вывода сообщений для получения полного примера.
Ведение журнала
Журнал изменений
Новое в версии 0.3.
Иногда вы можете столкнуться с ситуацией, когда вы работаете с данными, которые должны быть правильными, но на самом деле таковыми не являются. Например, у вас может быть код на стороне клиента, который отправляет HTTP-запрос на сервер, но он явно некорректен. Это может быть вызвано вмешательством пользователя в данные или сбоем кода клиента. В большинстве случаев в такой ситуации можно ответить 400 Bad
Request, но иногда этого недостаточно, и код должен продолжить работу.
Вы всё ещё можете вести журнал, чтобы записать, что произошло что-то подозрительное. Для этого полезны логи. Начиная с Flask 0.3, для вас предварительно настроен журнал.
Вот некоторые примеры вызовов логов:
app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')
Прикрепленный logger — это стандартный логгер Logger, поэтому для получения дополнительной информации посетите официальную документацию по логам.
Узнайте больше о ошибках приложения.
Включение WSGI-сред
Если вы хотите добавить WSGI-средство в своё приложение, вы можете обернуть внутреннее WSGI-приложение. Например, если вы хотите использовать одно из средств из пакета Werkzeug для решения проблем с lighttpd, вы можете сделать это так:
from werkzeug.contrib.fixers import LighttpdCGIRootFix app.wsgi_app = LighttpdCGIRootFix(app.wsgi_app)
Использование расширений Flask
Расширения — это пакеты, которые помогают выполнять распространённые задачи. Например, Flask-SQLAlchemy предоставляет поддержку SQLAlchemy, что упрощает и облегчает её использование с Flask.
Дополнительную информацию о расширениях Flask см. в Расширениях Flask.
Развёртывание на веб-сервере
Готовы развернуть своё новое приложение Flask? Перейдите к Вариантам развёртывания.
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/quickstart/