Фреймворк flask что это
Модуль Flask представляет собой микро-фреймворк, но слово "микро" не означает, что веб-приложение, построенное на Flask, должно помещаться в один файл с кодом на Python, хотя, это не запрещено. Или Flask испытывает недостаток в функциональности. Нет, приставка "микро" означает, что Flask придерживаться простого, но расширяемого ядра. Это означает, что Flask не решает за программиста что и как ему делать. При проектировании веб-приложений на Flask программист все решения принимает сам: например, какие паттерны использовать, какую базу данных подключить, использовать ли ORM или работать на чистом SQL. Flask не содержит больших слоев абстракции и по этому быстр. В общем Flask - это всё, что нужно, и ничего лишнего.
Фреймворк Flask поддерживает много расширений для добавления различной функциональности, которые обеспечивают интеграцию с базами данных, валидацию форм, различные технологии аутентификации и так далее. Flask имеет множество параметров конфигурации с разумными значениями по умолчанию, и мало предварительных соглашений. По соглашениям Flask, шаблоны и статические файлы хранятся в поддиректориях внутри дерева исходных кодов Python, с названиями templates и static соответственно, а в качестве движка шаблонов рекомендовано использовать модуль Jinja2 . Эти соглашения изменяемы, но изменять их не стоит, особенно тем, кто только начинает знакомится с Flask.
Содержание.
Уникальные URL-адреса (301 redirect).
Следующие два правила различаются использованием косой черты в конце URL-адреса.
В первом случае, канонический URL-адрес /projects/ имеет завершающую косую черту ( / в конце адреса), что похоже на папку в файловой системе. Если обратится к URL-адресу без косой черты в конце, то Flask перенаправляет с кодом ответа сервера 301 на канонический URL-адрес с завершающей косой чертой.
Во втором случае, канонический URL-адрес /about не имеет косой черты в конце. Доступ к URL-адресу с косой чертой в конце приведет к ошибке 404 "Not Found".
Такое поведение Flask помогает сохранить уникальность URL-адресов для этих ресурсов, что помогает поисковым системам избегать двойной индексации одной и той же страницы.
Structuring The Application Directory
We will use the exemplary name of LargeApp as our application folder. Inside, we are going to have a virtual environment (i.e. env) alongside the application package (i.e. app) and some other files such as “run.py” for running a test (development) server and “config.py” for keeping the Flask configurations.
The structure - which is given as an example below - is highly extensible and it is built to make use of all helpful tools Flask and other libraries offer. Do not be afraid when you see it, as we explain everything step by step by constructing it all.
Использование шаблонизатора Jinja2 в приложении Flask.
Генерировать HTML из Python - это неправильно и довольно громоздко, плюс ко всему этому встает необходимость самостоятельно выполнять экранирование HTML, чтобы обеспечить безопасность приложения. Что бы избежать всего этого фреймворк Flask автоматически настраивает шаблонизатор Jinja2.
Для визуализации шаблона используется функция flask.render_template() . Все, что нужно сделать, это указать имя подключаемого шаблона и передать переменные (как словарь или как ключевые аргументы) в подключенный шаблон. Вот простой пример того, как визуализировать шаблон:
Flask будет искать шаблоны в папке с шаблонами templates . Итак, если приложение является модулем (веб-приложение поместилось в один файл), то папка templates находится рядом с этим модулем (файлом), если это пакет, то templates находится внутри пакета (директории с веб-приложением):
Случай 1: приложение-модуль.
Случай 2: приложение-пакет.
В шаблонах используйте всю мощь движка Jinja2. Для получения дополнительной информации перейдите к документации по Jinja2.
Вот пример шаблона:
Внутри шаблонов, также есть доступ к объектам flask.request , flask.session и flask.g , а также к функции flask.get_flashed_messages() .
Движок Jinja2 особенно полезен при использовании наследования шаблонов. В основном, наследование шаблонов позволяет указать определенные элементы в базовом шаблоне, а потом переопределить их в дочерних шаблонах на каждой странице (например, заголовок, блок навигации, нижний колонтитул и т.д.).
В шаблонах включено автоматическое экранирование, следовательно, если переменная содержит HTML, то содержимое будет экранировано автоматически. Если вы доверяете содержимому переменной и знаете, что это будет безопасный HTML (например, он сгенерирован кодом веб-приложения), то можно пометить его как безопасный, используя класс flask.Markup или фильтр шаблона > .
Базовое введение в то, как работает класс Markup :
Installing Flask And Application Dependencies
Once we have everything in place, to begin our development with Flask, let’s download and install it using pip.
Run the following to install Flask inside the virtual environment env.
Note: Here we are downloading and installing Flask without activating the virtual environment. However, given that we are using the pip from the environment itself, it achieves the same task. If you are working with an activated environment, you can just use pip instead.
And that’s it! We are now ready to build a larger Flask application modularized using blueprints.
Step 1: Structuring The Module
As we have set out to do, let us create our first module’s ( mod_auth ) directories and files to start working on them.
After these operations, this is how the folder structure should look like:
4. Structuring The Application Directory
- Creating Application Folder
- Creating A Virtual Environment
- Creating Application Files
- Installing Flask
Our Choices In This Article
As we have just been over in the previous section, Flask-way of doing things involves using the tools you are most comfortable with. In our article, we will be using – perhaps – the most common (and sensible) of choices in terms of extensions and libraries (i.e. database extraction layer). These choices will involve:
SQLAlchemy (via Flask-SQLAlchemy)
WTForms (via Flask-WTF)
Creating A Module / Component
This section is the first major step that defines the core of this article. Here, we will see how to use Flask’s blueprints to create a module (i.e. a component).
What’s brilliant about this is the offered portability and reusability of your code, combined with ease of maintenance - for which you will be thankful in the future as often it is quite bit of a struggle to come back and understand things as they were left.
2. Our Choices In This Article
Edit “run.py” using nano
Place the contents:
Save and exit using CTRL+X and confirm with with Y.
Установка и получение файлов cookie во Flask.
Для доступа к файлам cookie можно использовать атрибут request.cookie . Чтобы установить файлы cookie , можно использовать метод response.set_cookie() объекта ответа. Атрибут cookie объектов запроса Request представляет собой словарь со всеми файлами cookie , передаваемыми клиентом. Если нужно использовать сессии/сеансы, то не используйте cookie напрямую, а вместо этого используйте встроенные сессии Sessions во Flask, которые повышают безопасность файлов cookie .
Чтение файлов cookie :
Установка файлов cookie :
Обратите внимание, что файлы cookie устанавливаются для объектов Responses. Поскольку вы обычно просто возвращаете строки из функций просмотра, Flask преобразует их для вас в объекты ответа. Если вы явно хотите сделать это, вы можете использовать функцию make_response (), а затем изменить ее.
Иногда вам может потребоваться установить cookie в точке, где объект ответа еще не существует. Это возможно с помощью шаблона обратных вызовов отложенного запроса.
Так же смотрите ниже подраздел "Ответ сервера во Flask".
Step 2: Define The Module Data Model(s)
Place the below self-explanatory - exemplary - contents:
Save and exit using CTRL+X and confirm with with Y.
Setting up Python, pip and virtualenv
On Ubuntu and Debian, a recent version of Python interpreter - which you can use - comes by default. It leaves us with only a limited number of additional packages to install:
python-dev (development tools)
pip (to manage packages)
virtualenv (to create isolated, virtual
Note: Instructions given here are kept brief. To learn more, check out our how-to article on pip and virtualenv: Common Python Tools: Using virtualenv, Installing with Pip, and Managing Packages.
pip is a package manager which will help us to install the application packages that we need.
Run the following commands to install pip:
flask-testing
Штука, призванная помочь с тестами. Например, можно заглянуть в контекст, который передается в шаблон. А давайте попробуем:
Ой. Что-то пошло не так. А знаете что? Я вот тоже не знаю.
На самом деле (ненавижу это выражение), я схватил NotImplementedError в одном из методов, которые не переопределил. Но поинт в том, что уронив тесты, вам ни за что не понять в чем причина.
Creating The Application
In this section, we will continue on the previous steps and start with actual coding of our application before moving onto creating our first modularized component (using blueprints): mod_auth for handling all authentication related procedures (i.e. signing-in, signing-up, etc).
Creating Application Files
In this step, we will form the basic application files before moving on to working with modules and blueprints.
Run the following to create basic application files:
Автоматическое построение (генерация) URL-адресов.
Автоматическое создать URL-адрес для декорированных @app.route() функций, используйте функцию flask.url_for() . В качестве первого аргумента flask.url_for() принимает имя декорированной функции и любое количество ключевых аргументов, каждый из которых соответствует изменяемой части URL-адреса. Если дополнительно указываются переменные, которые отсутствует в изменяемых частях URL-адреса, то все они добавляются к URL в качестве параметров запроса.
В примере использован метод app.test_request_context() , который заставляет Flask вести себя так, как будто он обрабатывает запрос, даже при взаимодействии с ним через интерпретатор Python.
Зачем строить URL-адреса с помощью flask.url_for() , ведь их можно составить при помощи переменных в шаблонах?
- Использование flask.url_for() часто более понятно (первый аргумент - функция, которая отвечает за страницу), чем жесткое кодирование URL-адресов.
- Можно изменить URL-адреса за один раз, вместо ручного поиска и изменения жестко закодированных URL-адресов.
- Автоматическое построение URL-адресов прозрачно обрабатывает экранирование специальных символов и данных Unicode.
- Сгенерированные пути URL-адреса всегда абсолютны, что позволяет избежать неожиданного поведения относительных путей в браузерах.
- Если приложение размещено за пределами корневого URL-адреса / , например в /myapplication , то функция flask.url_for() обработает все правильно.
Режим отладки веб-приложения Flask.
Существует три способа включить отладку:
Через FLASK_ENV (Если используется Flask 1.1 и выше)
Внимание! Включенный интерактивный отладчик позволяет выполнение произвольного кода Python. Это делает его главной угрозой безопасности, и следовательно режим debug никогда не должен использоваться на "боевых" серверах.
Как сгенерировать хорошие секретные ключи?
Секретный ключ должен быть как можно более случайным. В операционной системе есть способы cгенерировать случайные данные на основе криптографического генератора случайных чисел. Используйте функцию os.urandom() , чтобы быстро сгенерировать значение для Flask.secret_key или app.config['SECRET_KEY'] ). Например:
*Примечание о сеансах на основе файлов cookie :
Flask принимает значения, которые вводятся в объект сессии/сеанса, и преобразует их в файл cookie . Если вдруг обнаружите, что некоторые значения не сохраняются в запросах (четкой ошибки не будет), то необходимо проверить в настройках Вашего браузера, что файлы cookie действительно включены. Так же проверьте размер cookie в ответах страницы, он должен быть меньше размера, поддерживаемым веб-браузерами.
Помимо клиентских сеансов/сессий встроенных в Flask, есть несколько расширений, которые добавляют возможность обрабатывать сеансы на стороне сервера.
Edit “config.py” using nano
Place the contents:
Save and exit using CTRL+X and confirm with with Y.
Flask приложение «Привет, мир»
Если вы зайдете на сайт Flask, вас приветствует очень простое примерное приложение с пятью строками кода. Вместо того, чтобы повторять этот тривиальный пример, я покажу вам немного более сложный, который даст вам хорошую базовую структуру для написания больших приложений.
Приложение будет существовать в виде пакета.
Прим.переводчика: Пакет — это коллекция модулей.
В Python подкаталог, содержащий файл __init__.py , считается пакетом и может быть импортирован. Когда вы импортируете пакет, __init__.py выполняет и определяет, какие символы предоставляют пакет для внешнего мира.
Давайте создадим пакет под названием app , в котором будет размещено приложение. Убедитесь, что вы находитесь в каталоге microblog , а затем выполните следующую команду:
__init__.py для пакета приложения будет содержать следующий код:
Сценарий выше просто создает объект приложения как экземпляр класса Flask, импортированного из пакета flask. Переменная __name__ , переданная в класс Flask, является предопределенной переменной Python, которая задается именем модуля, в котором она используется. Flask использует расположение модуля, переданного здесь как отправную точку, когда ему необходимо загрузить связанные ресурсы, такие как файлы шаблонов, которые я расскажу в главе 2. Для всех практических целей передача __name__ почти всегда будет настраивать flask в правильном направлении. Затем приложение импортирует модуль routes , который еще не существует.
Один из аспектов, который может показаться запутанным вначале, состоит в том, что существуют два объекта с именем app. Пакет приложения определяется каталогом приложения и сценарием __init__.py и указан в инструкции routes импорта приложения. Переменная app определяется как экземпляр класса Flask в сценарии __init__.py , что делает его частью пакета приложения.
Другая особенность заключается в том, что модуль routes импортируется внизу, а не наверху скрипта, как это всегда делается. Нижний импорт является обходным путем для циклического импорта, что является общей проблемой при использовании приложений Flask. Вы увидите, что модуль routes должен импортировать переменную приложения, определенную в этом скрипте, поэтому, поместив один из взаимных импортов внизу, вы избежите ошибки, которая возникает из взаимных ссылок между этими двумя файлами.
Так что же входит в модуль routes ? routes — это разные URL-адреса, которые приложение реализует. В Flask обработчики маршрутов приложений записываются как функции Python, называемые функциями просмотра. Функции просмотра сопоставляются с одним или несколькими URL-адресами маршрутов, поэтому Flask знает, какую логику следует выполнять, когда клиент запрашивает данный URL-адрес.
Вот ваша первая функция просмотра, которую вам нужно написать в новом модуле с именем app/routes.py :
Эта функция просмотра на самом деле довольно проста, она просто возвращает приветствие в виде строки. Две странные строки @app.route над функцией — декораторы, уникальная особенность языка Python. Декоратор изменяет функцию, которая следует за ней. Общий шаблон с декораторами — использовать их для регистрации функций как обратных вызовов для определенных событий. В этом случае декоратор @app.route создает связь между URL-адресом, заданным как аргумент, и функцией. В этом примере есть два декоратора, которые связывают URL-адреса / и /index с этой функцией. Это означает, что когда веб-браузер запрашивает один из этих двух URL-адресов, Flask будет вызывать эту функцию и передавать возвращаемое значение обратно в браузер в качестве ответа. Если вам кажется, что это еще не имеет смысла, это будет недолго, пока вы запустите это приложение.
Чтобы завершить приложение, вам нужно создать сценарий Python на верхнем уровне, определяющий экземпляр приложения Flask. Давайте назовем этот скрипт microblog.py и определим его как одну строку, которая импортирует экземпляр приложения:
Помните два объекта app ? Здесь вы можете видеть оба вместе в одном предложении. Экземпляр приложения Flask называется app и входит в пакет app. from app import app импортирует переменную app , входящую в пакет app. Если вы считаете это запутанным, вы можете переименовать либо пакет, либо переменную во что то другое.
Чтобы убедиться, что вы все делаете правильно, ниже приведена диаграмма структуры проекта:
Верьте или нет, но первая версия приложения завершена! Прежде чем запускать его, Flask нужно сообщить, как его импортировать, установив переменную среды FLASK_APP :
Если вы используете Microsoft Windows, используйте команду 'set' вместо 'export' в команде выше.
Готовы ли вы быть потрясены? Вы можете запустить свое первое веб-приложение со следующей командой:
Прим.переводчика: Я был потрясен поскольку получил ошибку кодировки. Если у вас версия Python старше 3.6 вас скорее всего ждет сюрприз. Типа:
В моем случае виноваты кириллические символы ПК в имени компьютера. Заменил на PK и все заработало. Виноват модуль socket
Действительно все заработало:
Что бы написать по русски "Привет, Мир!" потребуется скорректировать
модуль routes.py
Когда вы закончите играть с сервером, вы можете просто нажать Ctrl-C, чтобы остановить его.
Поздравляем, вы совершили первый большой шаг, чтобы стать веб-разработчиком!
There are many methods and conventions for structuring Python web applications. Although certain frameworks are shipped with tools (for scaffolding) to automate – and ease – the task (and the headaches), almost all solutions rely on packaging / modularizing applications as the codebase gets distributed [logically] across related files and folders.
The minimalist web application development framework Flask, has its own - blueprints.
In this DigitalOcean article, we are going to see how to create an application directory, and structure it to work with re-usable components created with Flask’s blueprints. These pieces allow (and simplify) the maintenance and the development of application components greatly.
Blueprints
Если в джанге все приложения подключаются в INSTALLED_APPS , то во фласке используется концепция blueprints . Этакое приложение и обособленный неймспейс урлов в одном флаконе:
Далее, можно роутить урлы так: url_for('simple_page.index') .
Module Templates
To support modularizing to-the-max, we will structure the “templates” folder to follow the above convention and contain a new folder – with the same or a similar, related name as the module – to contain its template files.
Target example templates directory structure (inside LargeApp ):
Стейк!
А. Погодите. Это мне. Омн-омн-омн.
url_for()
Допустим, вы хотите сделать так:
Забудьте. Вне контекста не работает. Наверное, можно сделать свой ленивый объект, в конце-концов, в джанге это тоже не сразу появилось.
Загрузка файлов на сервер.
Можно легко обрабатывать загруженные файлы с помощью Flask, при этом необходима установка атрибута enctype='multipart/form-data' в HTML-форме, иначе браузер вообще не будет передавать файлы.
Загруженные файлы хранятся в памяти или во временном каталоге файловой системы. Получить доступ к файлам, можно при помощи атрибута request.files объекта запроса. Каждый загруженный файл хранится в этом словаре. Он ведет себя так же, как стандартный файловый объект Python, но также имеет метод fp.save() , который позволяет сохранять файл в указанном месте файловой системе. Простой пример, как это работает:
Если необходимо знать, как изначально назывался файл, до того, как он был загружен, то можно получить доступ к атрибуту имени файла fp.filename . Имейте в виду, что это значение может быть подделано, следовательно доверять этому значению нельзя. Если необходимо использовать изначальное имя файла для его хранения на сервере, то лучше получить его через функцию werkzeug.utils.secure_filename() , которую предоставляет пакет Werkzeug :
Дополнительно смотрите раздел "Загрузка файлов во Flask".
Step 5: Set Up The Application in “app/init.py”
Place the contents:
Save and exit using CTRL+X and confirm with with Y.
Вложенность
А ее нет. Нельзя просто так взять и сделать вложенный неймспейс. В сети можно найти "решения", но здесь я буду рассматривать только коробочный фласк, потому что написать-то можно все.
Сессии/сеансы во Flask.
В дополнение к объекту flask.request существует также второй объект flask.session , называемый сеансом/сессией, который позволяет хранить информацию, которая будет передаваться от одного запроса к другому. Сессии реализованы поверх файлов cookie , при этом cookie криптографически подписываются. Это означает, что пользователь может просматривать содержимое файла cookie , но не зная секретного ключа изменить его не сможет.
Чтобы использовать сессии/сеансы, необходимо установить секретный ключ, при помощи которого будут подписываться сессионные cookie .
Установка Python
Если на вашем компьютере не установлен Python, установите его. Если ваша операционная система не имеет предустановленный пакет Python, вы можете скачать программу установки с официального сайта Python. Если вы используете Microsoft Windows вместе с WSL или Cygwin, обратите внимание, что вы не будете использовать родную версию Python для Windows, а версию, совместимую с Unix, которую вам нужно получить от Ubuntu (если вы используете WSL) или от Cygwin.
Чтобы убедиться, что ваша установка Python является функциональной, вы можете открыть окно терминала и ввести python3, или если это не работает, просто python. Вот что вам следует ожидать:
или так в cmd (окно командной строки Microsoft Windows) :
Интерпретатор Python теперь находится в ожидании пользовательского ввода. В будущих главах вы узнаете, для чего это интерактивное приглашение полезно. Но пока Вы подтвердили, что Python установлен в вашей системе. Чтобы выйти из интерактивного приглашения, вы можете ввести exit() и нажать Enter.
В версиях Python для Linux и Mac OS X вы также можете выйти из интерпретатора, нажав Ctrl-D .
В Windows, комбинация клавиш для выхода — Ctrl-Z , затем Enter.
Локальные переменные контекста запроса.
Данные, которые клиент отправляет на сервер передаются в глобальном объекте request . Этот объект фактически является прокси для объектов, которые в свою очередь являются локальными для определенного контекста, немного запутанно, но это легко понять.
Представьте, что контекст является потоком обработки. Приходит запрос, и веб-сервер решает создать новый поток или что-то еще, т.к. базовый объект может работать с системами, отличными от потоков. Когда Flask начинает обработку внутреннего запроса, он определяет, является ли текущий поток активным контекстом, и связывает текущее приложение и среду WSGI с этим контекстом (потоком). Он делает это так, что одно приложение может вызывать другое приложение без прерывания работы.
Что это значит? По сути, это можно полностью игнорировать, если только не используется модульное тестирование. Код, зависящий от объекта запроса, сломается из-за отсутствия объекта запроса. Решение состоит в том, чтобы самостоятельно создать объект запроса и привязать его к контексту. Самым простым решением для модульного тестирования является использование диспетчера контекста app.test_request_context() . В сочетании с оператором with он связывает тестовый запрос для взаимодействия с ним. Вот пример:
Другая возможность передать среду WSGI методу app.request_context() :
Установка Flask
Следующий шаг — установить Flask, но прежде чем я расскажу об этом, я хочу рассказать вам о лучших методах, связанных с установкой пакетов Python.
В Python пакеты, такие как Flask, доступны в общем репозитории, откуда их можно загрузить и установить. Официальный репозиторий пакетов Python называется PyPI, что означает Python Package Index (также известный, как «cheese shop»). Установка пакета из PyPI очень проста, потому что у Python есть инструмент под названием pip, который выполняет эту работу (в Python 2.7 pip не входит в комплект с Python и его нужно устанавливать отдельно).
Чтобы установить пакет на свой компьютер, вы используете pip следующим образом:
Интересно, что этот метод установки пакетов не будет работать в большинстве случаев. Если ваш интерпретатор Python был установлен глобально для всех пользователей вашего компьютера, велика вероятность того, что ваша обычная учетная запись пользователя не получит разрешения на внесение в нее изменений, поэтому единственный способ выполнить вышеприведенную команду — запустить ее от имени администратора. Но даже без этого осложнения поймите, что происходит, когда вы устанавливаете пакет, как указанным выше способом. Инструмент pip загрузит пакет из PyPI, а затем добавит его в вашу папку Python. С этого момента каждый скрипт Python, который у вас есть в вашей системе, будет иметь доступ к этому пакету. Представьте ситуацию, когда вы закончили веб-приложение с использованием версии 0.11 Flask, которая была самой последней версией Flask при запуске, но теперь она была заменена версией 0.12. Теперь вы хотите запустить второе приложение, для которого вы хотели бы использовать версию 0.12, но если вы замените установленную версию 0.11, вы рискуете сломать свое старое приложение. Вы видите проблему? Было бы идеально, если бы можно было установить Flask 0.11, который будет использоваться вашим старым приложением, а также установить Flask 0.12 для Вашего нового.
Чтобы решить проблему поддержки различных версий пакетов для разных приложений, Python использует концепцию виртуальных сред. Виртуальная среда — это полная копия интерпретатора Python. Когда вы устанавливаете пакеты в виртуальной среде, общесистемный интерпретатор Python не затрагивается, только копия. Таким образом, решение иметь полную свободу для установки любых версий ваших пакетов для каждого приложения — использовать другую виртуальную среду для каждого приложения. Виртуальные среды имеют дополнительное преимущество, они принадлежат пользователю, который их создает, поэтому им не требуется учетная запись администратора.
Начнем с создания каталога, в котором будет жить проект. Я собираюсь назвать этот каталог microblog, так как это имя приложения:
Если вы используете версию Python 3, в нее включена поддержка виртуальной среды, поэтому все, что вам нужно сделать для ее создания, это:
С помощью этой команды Python запустит пакет venv , который создает виртуальную среду с именем venv . Первым venv в команде является имя пакета виртуальной среды Python, а второе — имя виртуальной среды, которое я буду использовать для этой конкретной среды. Если вы считаете, что это сбивает с толку, вы можете заменить второй venv другим именем, которое вы хотите назначить своей виртуальной среде. В общем, я создаю свои виртуальные среды с именем venv в каталоге проекта, поэтому всякий раз, когда я подключаюсь к проекту, я нахожу его соответствующую виртуальную среду.
Обратите внимание, что в некоторых операционных системах вам может понадобиться использовать python вместо python3 в приведенной выше команде. Некоторые установки используют python для релизов Python 2.x и python3 для релизов 3.x, в то время как другие отображают python в выпусках 3.x.
По завершении команды вы будете иметь каталог с именем venv , где хранятся файлы виртуальной среды.
Если вы используете любую версию Python старше 3.4 (включая выпуск 2.7), виртуальные среды не поддерживаются изначально. Для этих версий Python вам необходимо загрузить и установить сторонний инструмент virtualenv, прежде чем создавать виртуальные среды. После того, как virtualenv установлен, вы можете создать виртуальную среду со следующей командой:
Прим.переводчика: У меня установлено несколько версий Python. Я использую Python3.3. В моем случае пришлось вводить строку так:
Независимо от метода, который вы использовали для его создания, вы создали свою виртуальную среду. Теперь вам нужно сообщить системе, что вы хотите ее использовать, активируя ее. Чтобы активировать новую виртуальную среду, используете следующую команду:
Если вы используете cmd (окно командной строки Microsoft Windows), команда активации немного отличается:
Когда вы активируете виртуальную среду, конфигурация сеанса терминала изменяется так, что интерпретатор Python, хранящийся внутри нее, станет тем, который вызывается при вводе python . Кроме того, в запросе терминала включено имя активированной виртуальной среды. Изменения, внесенные в сеанс терминала, являются временными и частными для этого сеанса, поэтому они не будут сохраняться при закрытии окна терминала. Если вы одновременно работаете с несколькими терминальными окнами, отлично видно, чтобы на каждом из них были задействованы разные виртуальные среды.
Теперь, когда вы создали и активировали виртуальную среду, вы можете, наконец, установить в нее Flask:
Если вы хотите проверить, что в вашей виртуальной среде установлен Flask, вы можете запустить интерпретатор Python и импортировать Flask в него:
Если этот импорт не дает вам никаких ошибок, вы можете поздравить себя, так как Flask установлен и готов к использованию.
Flask-SQLAlchemy
Adds SQLAlchemy support to Flask. Quick and easy.
This is an approved extension.
flask-wtf. CSRF
Ох. Допустим, нам нужно отключить проверку в одной вьюхе:
Значит, нам нужен app . Помните про импорты, да? Ищем выход, лезем в сорцы:
Ура! Можно передать путь до вьюхи (в версии, которая вышла две недели назад)! Пробуем:
Не работает. На самом деле (ненавижу это выражение), мы подменили имя вьюхи, когда вызывали ApiView.as_view('api_view') :
И "все равно", что мы указываем путь до объекта, которого нет. Работает! Не работает.
А знаете почему? Потому что форма. Она ничегошеньки не знает про вьюху:
Вот теперь работает.
Step 7: See Your Module In Action
After having created our first module, it is time to see everything in action.
Run a development server using the run.py :
This will initiate a development (i.e. testing) server hosted at port 8080.
Visit the module by going to the URL:
Although you will not be able to login, you can see it in action by entering some exemplary data or by testing its validators.
URL маршрутизация в веб-приложении Flask.
Ранее говорилось, что для привязки функции к URL-адресу используется декоратор @app.route() . Но это еще не все, можно сделать определенные части URL динамически меняющимися, при этом задействовать несколько правил.
Роутинг урлов и их методы
У меня на сайте есть такой кусок урлов:
ApiView обрабатывает только один метод — POST . Угадайте, что будет если спросить GET ? Ага, 404. Ее обеспечивает вторая вьюшка.
Чтобы получить NOT ALLOWED , нужно явно вернуть 405 в ApiView !
Fask, что с тобой не так?
7. Creating A Module / Component
- Step 1: Structuring The Module
- Step 2: Define The Module Data Model(s)
- Step 3: Define Module Forms
- Step 4: Define Application Controllers (Views)
- Step 5: Set Up The Application in “app/init.py”
- Step 6: Create The Templates
- Step 7: See Your Module In Action
Подключение статических файлов CSS и JavaScript.
Динамическим веб-приложениям также нужны статические файлы - это CSS и JavaScript файлы. Веб-сервер Flask настроен на их обслуживание в директории static . Во время разработки нужно создать папку с именем static в пакете с веб-приложением или рядом с приложением-модулем (приложение состоит из одного файла), и она будет доступна в приложении по URL /static .
Чтобы сгенерировать URL-адреса для статических файлов, необходимо использовать специальное имя конечной точки 'static' :
Файл должен храниться в файловой системе как static/style.css .
virtualenv
It is best to contain a Python application within its own environment together with all of its dependencies. An environment can be best described (in simple terms) as an isolated location (a directory) where everything resides. For this purpose, a tool called virtualenv is used.
Run the following to install virtualenv using pip:
Working With Modules And Blueprints (Components)
Flask-WTF
Flask-WTF offers simple integration with WTForms. This integration includes optional CSRF handling for greater security.
This is an approved extension.
6. Creating The Application (run.py, init.py, etc.)
Flask
Flask — это обертка над очень крутыми обособленными проектами. Некоторые сравнивают его с джангой. Я хз почему.
Если попытаться описать все проблемы фласка в двух пунктах:
Все. Дальше можно не читать. Но если все еще не понятно, листаем дальше.
5. Working With Modules And Blueprints (Components)
Правила для переменной части URL-адреса.
Для составления динамически меняющихся URL-адресов, необходимо изменяемые части адреса выделять как . Затем эти части передаются в функцию, в виде аргумента с именем variable_name . Также в изменяемых частях может быть использован конвертер, который задает правила следующего вида .
Несколько интересных примеров:
В Flask существуют следующие конвертеры:
- int : принимаются целочисленные значения;
- float : принимаются значения с плавающей точкой;
- path : принимает строки (как по умолчанию), но также принимает слеши;
- uuid : принимает строки UUID.
1. Flask: The Minimalist Application Development Framework
Glossary
Ответ сервера во Flask.
Возвращаемое значение из функции представления, автоматически преобразуется в объект ответа сервера. Если возвращаемое значение является строкой, то оно преобразуется в объект ответа со строкой в качестве тела ответа, кодом состояния 200 OK и mimetype text/html . Если возвращаемое значение - словарь dict , то для получения ответа вызывается flask.jsonify() . Логика, которую Flask применяет для преобразования возвращаемых значений в объекты ответа, выглядит следующим образом:
- Если возвращается объект ответа правильного типа, то он возвращается непосредственно из функции представления.
- Если это строка, то создается объект ответа с этими данными и параметрами по умолчанию.
- Если это dict , то объект ответа создается с помощью flask.jsonify() .
- Если возвращается кортеж, то элементы в кортеже предоставляют дополнительную информацию. Такие кортежи должны выглядеть следующим образом (response, status) , (response, headers) или (response, status, headers) . Значение кортежа status будет иметь приоритет над кодом статуса сервера, а заголовки headers могут быть списком или словарем дополнительных значений заголовков.
Если ничего из этого не сработает, то Flask будет считать, что возвращаемое значение является допустимым приложением WSGI, и преобразует его в объект ответа.
Если необходимо получить объект response внутри функции представления, то можно использовать функцию flask.make_response() .
Представьте, что есть такая функция-представление:
Для получения объекта response , нужно обернуть возвращаемое выражение с помощью flask.make_response() , далее можно его изменить, а затем вернуть его:
Creating Application Folders
Let’s start with creating the main folders we need.
Run the following commands successively to perform the task:
3. Preparing The System For Flask
- Prepare The Operating System
- Setting up Python, pip and virtualenv
Установка веб-фреймворка Flask в виртуальное окружение.
Веб-фреймворк Flask зависит от двух внешних библиотек - это Werkzeug и Jinja2 . Библиотека Werkzeug - это инструментарий для WSGI - стандартного интерфейса Python между веб-приложениями и различными серверами и предназначен как для разработки, так и развёртывания. Модуль Jinja2 занимается обработкой и визуализацией шаблонов с HTML.
Что бы установить Flask в виртуальное окружение, необходимо выполнить следующие инструкции в терминале вашей системе.
Минимальное веб-приложение на Flask.
Как говорилось ранее, фреймворк Flask очень гибкий и не запрещает размещение всего веб-приложения в одном файле, и может выглядеть примерно следующим образом:
Код выше сохраним в файл с именем mini-flask.py и запустим с помощью Python в виртуальном окружении, куда ранее устанавливался пакет Flask. Внимание! никогда не давайте имя файлу flask.py или директории с веб-приложением (если оно большое), это вызовет конфликт с установленным пакетом Flask.
Далее запускаем файл с кодом минимального приложения.
Если используется Flask 2.0 и выше, то приложение так же можно запустить следующим образом:
Разберем, что здесь происходит: (это необходимо понять)
Как видно из информации, которую выводит сервер отладки при запуске веб-приложения (см. выше), для его остановки, необходимо нажать комбинацию клавиш Ctrl + C .
Публично доступный сервер веб-приложения Flask:
Если используется Flask 2.0 и выше, то сделать приложение общедоступным можно просто добавив --host=0.0.0.0 в командную строку:
Flask: The Minimalist Application Development Framework
Flask is a minimalist (or micro) framework which refrains from imposing the way critical things are handled. Instead, Flask allows the developers to use the tools they desire and are familiar with. For this purpose, it comes with its own extensions index and a good amount of tools already exist to handle pretty much everything from log-ins to logging.
It is not a strictly “conventional” framework and relies partially on configuration files, which frankly make many things easier when it comes to getting started and keeping things in check.
Создание API с JSON во Flask.
Распространенным форматом ответа при написании API является JSON. Начать писать такой API с помощью Flask несложно. Если возвращать словарь dict из функции-представления, то он будет преобразован в ответ JSON.
В зависимости от дизайна API можно создавать ответы JSON для типов, отличных от словаря dict . В этом случае используйте функцию flask.jsonify() , которая сериализует любой поддерживаемый тип данных JSON. Или используйте расширения сообщества Flask, которые поддерживают более сложные приложения.
Step 6: Create The Templates
Place the contents:
Save and exit using CTRL+X and confirm with with Y.
Note: This template file is a very simple and incomplete example that has just been created for demonstration purposes. You are highly encouraged to read the Jinja2 documentation and use base files to build your website’s templates.
Creating A Virtual Environment
Using a virtual environment brings with it a ton of benefits. You are highly suggested to use a new virtual environment for each one of of your applications. Keeping the virtualenv folder inside your application’s is a good way of keeping things in order and tidy.
Run the following to create a new virtual environment with pip installed.
Ведение журнала во Flask.
Если специально не настраивать ведение журнала, то уровень журнала Python по умолчанию обычно warning .
Еще несколько примеров вызовов журнала:
Встроенный app.logger является стандартным регистратором ведения журнала, поэтому для получения дополнительной информации смотрите документацию модуля logging .
Вообще-то, это картинка от wtforms, но у меня гимп почему-то не запускается.
Эту статью я пишу в баре. Очень хочется похоливарить, но бармен на меня смотрит круглыми глазами, а кальянщик просто улыбается и мотает головой.
Однажды, меня спросили: что плохого во flask? Тогда меня полностью устраивал этот милый фреймворк. Поработав с ним какое-то время, я написал все, что думаю, в рабочий слак, на что мне ответили: "Мурад, будь добрее". Вообще, я добрый и пушистый, но wtf?!
Стоит отметить, что я являюсь большим поклонником работы Армина. Его пакеты используются во многих мои проектах. А еще он невероятная заноза в сообществе Python. И это хорошо.
Prepare The Operating System
In order to have a stable server, we must have all relevant tools and libraries up-to-date and well maintained.
To ensure that we have the latest available versions of default applications, let’s begin with updates.
Run the following for Debian Based Systems (i.e. Ubuntu, Debian):
To get the necessary development tools, install “build-essential” using the following command:
Preparing The System For Flask
Before we begin structuring a large Flask application, let’s prepare our system and download (and install) Flask distribution.
Note: We will be working on a freshly instantiated droplet running the latest version of available operating systems (i.e. Ubuntu 13). You are highly advised to test everything on a new system as well - especially if you are actively serving clients.
Module Basics
At this point, we have both our application structure set up and its dependencies downloaded and ready.
Our goal is to modularize (i.e. create re-usable components with Flask’s blueprints) all related modules that can be logically grouped.
An example for this can be an authentication system. Having all its views, controllers, models and helpers in one place, set up in a way that allows reusability makes this kind of structuring a great way for maintaining applications whilst increasing productivity.
Target example module (component) structure (inside /app ):
Want to learn more? Join the DigitalOcean Community!
Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.
Содержание.
flask.g
Нельзя не пошутить про одноименную точку. А главное, ее не нужно искать, она всегда тут: flask.g . Бада-бум-тсс!
Вот поэтому Армин — мой кумир!
В нее можно пробросить все необходимое:
Однако, это будет работать только в контексте реквеста, как и любые другие магические объекты фласка.
Step 4: Define Application Controllers (Views)
Place the below self-explanatory - exemplary - contents:
Save and exit using CTRL+X and confirm with with Y .
Всякое разное
В процессе ковыряния фласка, нашел несколько моментов:
Здесь что-то происходит. Это все, что я понимаю.
А теперь ягодки:
P.S. А чего я один эээ статьи пишу, м? Кто хочет на той неделе, скажем, во вторник (чтобы больше вместить) пойти в бар (в Питере, в районе Звездной). Пишите в инбокс.
Это первая статья в серии, где я буду документировать мой опыт написания веб-приложения на Python, используя микрофреймворк Flask.
Моя предыстория
Я разработчик ПО с двузначным числом лет опыта разработки комплексных приложений на нескольких языках. Впервые я познакомился с Python для создания привязок к C++ библиотеке на работе. Вдобавок к Python, я писал веб-приложения на PHP, Ruby, Smalltalk и, верите вы или нет, еще на С++. Из всего этого, я нахожу комбинацию Python/Flask самой гибкой.
Приложение
Приложение, которое я собираюсь разрабатывать как часть этого руководства, является сервером микроблогов, и я решил назвать его microblog. Довольно креативно, я знаю.
Во время нашего прогресса я затрону следующие темы:
- Управление пользователями, включая управление входами, сессиями, ролями пользователя, профилями и пользовательскими аватарами
- Управление базой данных, включая миграцию
- Поддержка форм, включая валидацию полей
- Пагинация длинных списков элементов
- Полнотекстовый поиск
- E-mail уведомления пользователей
- HTML шаблоны
- Поддержка нескольких языков
- Кеширование и другая оптимизация производительности
- Методы отладки для серверов разработки и продакшна
- Установка на продакшн сервер
Как видите, я весьма значительно берусь за все это. Надеюсь, что это приложение, когда я его закончу, станет чем-то вроде шаблона для написания других веб-приложений.
Требования
Если ваш компьютер поддерживает Python 2.6/2.7, то все, вероятно, пойдет хорошо. Приложение из руководства должно нормально работать на Windows, OS X и Linux.
Это руководство подразумевает, что вы знакомы с окном терминала (командной консолью в случае Windows), и вы знаете основные команды для работы с файлами вашей ОС. Если это не так, то перед тем как продолжить, я рекомендую вам ознакомиться с тем, как создавать директории, копировать файлы и т.д., используя консоль.
Наконец, вы должны чувствовать себя свободно в написании кода на Python. Знакомство с модулями и пакетами этого языка также не помешает.
Установка Flask
Ну что ж, приступим!
Если у вас еще не установлен Python 2.7, то берем его отсюда.
Теперь нам нужно установить Flask и несколько расширений, которые мы будем использовать. Я предпочитаю создание виртуального окружения, где все это будет установлено таким образом, что ваша основная установка Python затронута не будет. В качестве бонуса, вам не нужен будет root доступ для установки таким способом.
Итак, открываем терминал, выбираем место, где будет ваше приложение, и создаем новую папку, в которой оно будет содержаться. Назовем эту папку microblog .
Далее скачиваем virtualenv.py и кладем его внутрь новой папки.
Чтобы создать новое окружение введите следующую команду:
Эта команда создаст полноценное окружение Python внутри папки flask
Виртуальные окружения могут быть активированы и деактивированы по желанию. Активированное окружение добавляет путь своей папки bin в path системы, например, когда вы вызываете интерпретатор python, то получаете версию текущего окружения, а не системную. Лично я никогда не любил это свойство, поэтому ни разу не активировал ни одно из моих окружений, вместо этого я просто вызывал тот интерпретатор, который хотел, печатая его путь.
Прим. пер.: Перед тем как вы начнете вводить команды, хочу отметить, что в комментариях к девятой части отметится баг в flask-whooshalchemy, исправленную версию можнонужно скачать отсюда (репозиторий автора)
Если вы пользователь Linux, OS x или Cygwin, установите flask и расширения, вводя следующие команды одну за одной:
Эти команды скачают и установят все пакеты, которые мы будем использовать в нашем приложении.
Учтите, что мы собираемся использовать Flask 0.9, а не последнюю версию. Flask 0.10 не было довольно долго и некоторые расширения не готовы для работы с данной версией. Также есть несколько несовместимостей между пакетами и последней версией pip , которые решены использованием конкретных версий для установки.
Windows пользователей ждет еще один шаг. Наблюдательный читаель заметит, что в списке команд для Windows отсутствует flask-mail . Это расширение не устанавливается чисто на Windows, поэтому мы пойдем обходным путем:
Я не буду вдаваться в подробности, поэтому если вы хотите узнать больше, прочтите документацию к flask-mail.
Если установка всех пакетов прошла успешно, вы можете удалить virtualenv.py , поскольку файл нам больше не понадобится.
«Hello, World!» в Flask
Теперь у вас есть подпапка flask , в вашей папке microblog , содержащая интерпретатор Python и фреймворк Flask с расширениями, которые мы будем использовать в этом приложении. Настало время написать наше первое веб-приложение!
После того как вы переместились папку microblog , давайте создадим основную структуру папок для нашего приложения:
В папку app мы поместим само наше приложение. Подпапка static нужна для хранения статики, такой как картинки, javascript файлы и таблицы стилей. Подпапка templates , очевидно, предназначена для хранения наших шаблонов.
Давайте начнем с создания простого скрипта инициализации нашего пакета app (файл app/__init__.py )
Скрипт выше просто создает объект приложения (наследуя Flask ), затем импортирует модуль представлений, который мы еще не написали.
Представления — это обработчики, которые отвечают на запросы веб-браузера. Представления в Flask пишутся как Python функции. Каждая функция представления сопоставляется с одним или несколькими запросами URL.
Напишем нашу первую функцию представления (файл app/views.py )
Это весьма простое представление, которое просто возвращает строку для отображения в пользовательском браузере. Два декоратора route создают привязку адресов / и /index к этой функции.
Последним шагом для получения полностью работающего веб-приложения будет создание скрипта, который стартует веб-сервер нашего приложения. Давайте назовем скрипт run.py и положим его в корневой каталог ( microblog/ ):
Скрипт просто импортирует переменную app из нашего пакета app и вызывает метод run для того, чтобы запустить сервер. Помните, что переменная app — экземпляр класса Flask , мы создали его выше.
Для запуска вашего приложения просто запустите скрипт. На OS X, Linux и Cygwin вам следует пометить файл исполняемым перед тем как вы сможете его запустить.
Тогда скрипт может быть вызван просто:
В Windows процесс немного отличается. Нет необходимости помечать файл исполняемым. Вместо этого вам нужно запустить скрипт как аргумент интерпретатора Python:
После старта сервер будет прослушивать порт 5000, ожидая соединений. Теперь откроем браузер и введем следующий URL в адресную строку:
Или же вы можете использовать эту ссылку:
Теперь вы увидели маршрутизацию в действии? Первый URL привязан к / , в то время как второй к /index . Оба маршрута ассоциированы с нашей функцией представления, поэтому они дают одинаковый результат. Если вы введете любой другой маршрут, то получите ошибку, так как только эти два были привязаны к функции представления.
Когда вы закончите играть с сервером вы можете просто нажать Ctrl-C, чтобы остановить его.
И этим я хочу закончить первую часть этого руководства.
Те из вас, кто поленился печатать, могут скачать код из этого руководства ниже:
Обратите внимание, что вам нужно установить Flask, чтобы запустить приложение из архива выше.
Что дальше
В следующей части серии мы изменим наше маленькое приложение для использования HTML шаблонов.
Эта статья является переводом нового издания учебника Мигеля Гринберга. Прежний перевод давно утратил свою актуальность.
Автор планирует завершить его выпуск в мае 2018. Я, со своей стороны, постараюсь не отставать с переводом.
Для справки ниже приведен список статей этой серии.
Новый учебник написан в 2017 году, и, наконец, он выглядит так, как если бы он был настроен на версию Python 3. Решены проблемы с совместимостью, изменен фокус в сторону Python 3, а не Python 2 как было в 2012 году в прежней версии учебника.
К сожалению, Python 2 или 3 — это не единственное, что изменилось. Есть также несколько технологий, которые имели смысл в 2012 году, но теперь устарели. К ним относятся:
- Механизм аутентификации OpenID, который больше не поддерживается многими провайдерами.
- Пакет sqlalchemy-migrate для миграции баз данных, который, похоже, так же потерял поддержку сообщества. В эти дни Alembic — намного более лучший выбор для миграции чем SQLAlchemy.
- Интерфейс командной строки Flask (Flask Shell), который в то время не существовал, а теперь является незаменимым инструментом разработчика.
- В то время, когда Мигель начал работать над учебником, Flask blueprints были слишком новыми, поэтому он решил не использовать эту функцию. В 2017 году blueprints являются обязательными для применения в Flask.
- Bootstrap 2 для стилизации и форматирования веб-страниц, теперь имеет две основные версии. Новые версии Bootstrap не имеют обратной совместимости с версией 2.
- Изменения в сервисе Heroku, инструкции по развертыванию которые представлены учебнике устарели.
Многие вещи, которые изменились за эти пять лет, в основном означают, что нужно пересмотреть все главы, причем большинство из них претерпели довольно важные изменения.
Сам Мигель считает, что вырос профессионально за эти пять лет, и думает, что сможет принести гораздо большую ценность этому учебнику с этим новым опытом. После выхода первого учебника он провел более дюжины конференций и выпустил кучу учебных пособий, написал очень успешную книгу разработки Flask для крупного издательства, создал несколько популярных проектов с открытым исходным кодом .
Кроме того, у Мигеля есть еще пять лет опыта работы в качестве технического блоггера, так как продолжал создавать контент для своего блога на протяжении всех этих лет. Весь этот опыт будет отражен в обновлениях, которые он приводит в учебнике.
Более подробно читайте в блоге Мигеля
Примечание 1: Если вы ищете старые версии данного курса, это здесь.
Все примеры кода представленные в этом учебном курсе, размещены на GitHub. Загрузка кода из GitHub поможет вам сэкономить время, но я настоятельно рекомендую набирать код самостоятельно, по крайней мере, первые несколько глав. После того, как вы станете ближе знакомы с Flask можно получить доступ к коду прямо из GitHub, только в том случае, если ввод становится слишком утомительным.
В начале каждой главы, я дам вам три GitHub ссылки, которые могут быть полезны при изучении главы. Browse откроет GitHub репозиторий для микроблога в том месте, где собраны изменения к главе, которую Вы читаете, за исключением любых изменений, внесенных в будущих главах. Zip — это ссылка для загрузки zip-архива, в том числе приложения и изменений в главе. Diff — откроет графическое представление всех изменений, внесенных в главу, которую Вы собираетесь читать.
На GitHub ссылки в этой главе: Browse, Zip, Diff.
Перенаправление/редиректы во Flask.
По умолчанию для каждого кода ошибки (в примере выше строка с abort(401) ) отображается стандартная страница ошибки. Если необходимо настроить собственную страницу с ошибкой, то можно использовать декоратор @app.errorhandler() :
Обратите внимание на 404 после вызова flask.render_template() . Это сообщает Flask, что код состояния этой страницы должен быть 404 (обязательно нужно указать). По умолчанию функция будет возвращать код 200, что означает: все прошло хорошо.
Step 3: Define Module Forms
Place the below self-explanatory - exemplary - contents:
Save and exit using CTRL+X and confirm with with Y.
Доступ к данным запроса во Flask.
Здесь не будет рассматриваться подробно объект запроса flask.Request , а рассмотрим некоторые из наиболее распространенных операций. Прежде всего, необходимо импортировать его из модуля flask .
Для доступа к параметрам, представленным в URL-адресе как ?key=value , можно использовать атрибут request.args :
Полный список методов и атрибутов объекта запроса можно найти в документации по flask.Request .
Импорты
Когда вы делаете так в продакшен коде:
Где-то в мире грущу я! Берегите меня, выносите это в сеттинги.
Концептуально. Но работать не будет. Потому что пару строчек назад мы импортировали пакет в myapp и навечно заказали себе путь туда.
Погодите, должен быть выход! Ага!
И это не работает. Потому что current_app доступен только в контектсте реквеста!
— Вынеси это наконец в файл сеттингов приложения, больной ублюдок! — голос из зала.
— А как я буду их подменять на проде или тестовом, а?
Кстати, для джанги на этот случай у меня есть специальная батарейка.
Просто представьте себе прекрасный дивный мир, где django.conf.settings доступен только в контексте реквеста!
Экранирование HTML.
При возврате HTML (тип ответа по умолчанию во Flask) любые предоставленные пользователем значения, отображаемые в выходных данных, должны быть экранированы для защиты от атак с использованием инъекций. HTML-шаблоны, созданные с помощью Jinja2 сделают это автоматически.
Функцию escape() , показанную здесь, можно использовать вручную. В большинстве примеров она опущена для краткости, но всегда необходимо знать и понимать, как используются ненадежные данные.
Читайте также: