0 added
0 removed
Original
2026-01-01
Modified
2026-02-26
1
<p>Помимо форм поисковых, которые не изменяют данные, а только фильтруют их, существуют формы ввода данных. Они устроены сложнее как с клиентской стороны, так и с серверной. Для уверенной работы с ними необходимо разбираться в следующих вопросах:</p>
1
<p>Помимо форм поисковых, которые не изменяют данные, а только фильтруют их, существуют формы ввода данных. Они устроены сложнее как с клиентской стороны, так и с серверной. Для уверенной работы с ними необходимо разбираться в следующих вопросах:</p>
2
<ul><li>Знание соответствующих HTML-тегов</li>
2
<ul><li>Знание соответствующих HTML-тегов</li>
3
<li>Понимание того, как отправляются формы по HTTP</li>
3
<li>Понимание того, как отправляются формы по HTTP</li>
4
<li>Обработка на стороне сервера</li>
4
<li>Обработка на стороне сервера</li>
5
<li>Валидация и вывод ошибок</li>
5
<li>Валидация и вывод ошибок</li>
6
</ul><p>Начнем с того, что за вывод формы и ее обработку должны отвечать два разных обработчика - это разные маршруты. Один обработчик по GET-запросу выводит пустую форму для заполнения, второй обработчик по POST-запросу принимает отправленные данные. Ниже пример маршрутов для создания нового пользователя:</p>
6
</ul><p>Начнем с того, что за вывод формы и ее обработку должны отвечать два разных обработчика - это разные маршруты. Один обработчик по GET-запросу выводит пустую форму для заполнения, второй обработчик по POST-запросу принимает отправленные данные. Ниже пример маршрутов для создания нового пользователя:</p>
7
<ul><li>GET<em>/users/new</em>- страница с формой, которую заполняет пользователь. По нажатию кнопки отправить эта форма отправляет POST-запрос с данными на адрес<em>/users</em>, который указывается в атрибуте action</li>
7
<ul><li>GET<em>/users/new</em>- страница с формой, которую заполняет пользователь. По нажатию кнопки отправить эта форма отправляет POST-запрос с данными на адрес<em>/users</em>, который указывается в атрибуте action</li>
8
<li>POST<em>/users</em>- маршрут, который обрабатывает полученные данные формы</li>
8
<li>POST<em>/users</em>- маршрут, который обрабатывает полученные данные формы</li>
9
</ul><p>Подобная схема именования рекомендуется и автоматически создается многими фреймворками. Она хорошо ложится на REST-архитектуру, о которой мы еще поговорим.</p>
9
</ul><p>Подобная схема именования рекомендуется и автоматически создается многими фреймворками. Она хорошо ложится на REST-архитектуру, о которой мы еще поговорим.</p>
10
<p>Чтобы реализовать добавление нового пользователя, нам нужно добавить три составляющих: описание формы, маршрут, обработчик маршрута.</p>
10
<p>Чтобы реализовать добавление нового пользователя, нам нужно добавить три составляющих: описание формы, маршрут, обработчик маршрута.</p>
11
<h2>Форма</h2>
11
<h2>Форма</h2>
12
<p>Создадим новый шаблон<em>new.html</em>. В нем опишем поля сущности user:</p>
12
<p>Создадим новый шаблон<em>new.html</em>. В нем опишем поля сущности user:</p>
13
<h2>Обработка данных</h2>
13
<h2>Обработка данных</h2>
14
<p>Сперва рассмотрим как выглядит обработка полученных данных. Для задания маршрута воспользуемся декоратором @app.post(), который позволяет обрабатывать POST-запросы:</p>
14
<p>Сперва рассмотрим как выглядит обработка полученных данных. Для задания маршрута воспользуемся декоратором @app.post(), который позволяет обрабатывать POST-запросы:</p>
15
<p>Обработка данных формы начинается с извлечения данных из тела запроса. Это можно сделать двумя способами, похожими на то, как мы извлекаем параметры запроса:</p>
15
<p>Обработка данных формы начинается с извлечения данных из тела запроса. Это можно сделать двумя способами, похожими на то, как мы извлекаем параметры запроса:</p>
16
<ul><li>request.form.to_dict() - извлекает все данные и преобразовывает их в словарь</li>
16
<ul><li>request.form.to_dict() - извлекает все данные и преобразовывает их в словарь</li>
17
<li>request.form.get() - извлекает значение конкретного параметра. Вторым параметром принимает значение по умолчанию</li>
17
<li>request.form.get() - извлекает значение конкретного параметра. Вторым параметром принимает значение по умолчанию</li>
18
</ul><p>В нашем случае для извлечения данных мы используем метод request.form.to_dict():</p>
18
</ul><p>В нашем случае для извлечения данных мы используем метод request.form.to_dict():</p>
19
<p>Одно из главных правил веб-разработки - не доверять данным от пользователя. Все полученное от пользователей необходимо проверять на ошибки прежде чем внести в базу данных. Процесс проверки корректности данных называется<strong>валидацией</strong>. Flask, как и большинство микрофреймворков, не предоставляет механизмов для валидации. Но ее можно получить из сторонних библиотек.</p>
19
<p>Одно из главных правил веб-разработки - не доверять данным от пользователя. Все полученное от пользователей необходимо проверять на ошибки прежде чем внести в базу данных. Процесс проверки корректности данных называется<strong>валидацией</strong>. Flask, как и большинство микрофреймворков, не предоставляет механизмов для валидации. Но ее можно получить из сторонних библиотек.</p>
20
<p>В нашем случае валидация реализуется функцией validate(). Она проверяет данные формы и возвращает специальный словарь errors, в котором<strong>ключ</strong>- это название поля, а<strong>значение</strong>- выводимый в форме текст ошибки:</p>
20
<p>В нашем случае валидация реализуется функцией validate(). Она проверяет данные формы и возвращает специальный словарь errors, в котором<strong>ключ</strong>- это название поля, а<strong>значение</strong>- выводимый в форме текст ошибки:</p>
21
<p>Если ошибок нет, то данные формы сохраняются, например, в базу данных. После сохранения обычно выполняется перенаправление - HTTP-redirect. За перенаправление отвечает заголовок<em>Location</em>и статусы с кодом<em>3XX</em>:</p>
21
<p>Если ошибок нет, то данные формы сохраняются, например, в базу данных. После сохранения обычно выполняется перенаправление - HTTP-redirect. За перенаправление отвечает заголовок<em>Location</em>и статусы с кодом<em>3XX</em>:</p>
22
<p>Если в процессе обработки возникли ошибки, выполняется рендеринг формы из того же шаблона, что мы использовали для<em>/users/new</em>. В этот шаблон передаются как данные формы, так и список ошибок. Редирект не происходит, а в адресной строке остается адрес<em>/users</em>.</p>
22
<p>Если в процессе обработки возникли ошибки, выполняется рендеринг формы из того же шаблона, что мы использовали для<em>/users/new</em>. В этот шаблон передаются как данные формы, так и список ошибок. Редирект не происходит, а в адресной строке остается адрес<em>/users</em>.</p>
23
<p>Если попробовать в этот момент нажать f5, то браузер выдаст предупреждение о том, что мы пытаемся повторно отправить данные. Это сообщение предупреждает о том, что метод POST не идемпотентен, и повторная отправка формы может привести к повторному созданию пользователя. Вернем соответствующий статус с кодом<em>4XX</em>, что укажет на ошибку со стороны пользователя:</p>
23
<p>Если попробовать в этот момент нажать f5, то браузер выдаст предупреждение о том, что мы пытаемся повторно отправить данные. Это сообщение предупреждает о том, что метод POST не идемпотентен, и повторная отправка формы может привести к повторному созданию пользователя. Вернем соответствующий статус с кодом<em>4XX</em>, что укажет на ошибку со стороны пользователя:</p>
24
<p>Вернемся к нашей форме и изменим ее, чтобы в нее подставлялись как возникающие ошибки, так и значения полей, которые вводились пользователем:</p>
24
<p>Вернемся к нашей форме и изменим ее, чтобы в нее подставлялись как возникающие ошибки, так и значения полей, которые вводились пользователем:</p>
25
<p>Такое изменение формы требует изменения обработчика<em>/users/new</em>. Чтобы избежать ошибок, необходимо передать в шаблон пустые словари errors и user, в котором необходимо задать значения по умолчанию для соответствующих полей формы. Так в шаблоне не придется выполнять проверку данных формы на существование:</p>
25
<p>Такое изменение формы требует изменения обработчика<em>/users/new</em>. Чтобы избежать ошибок, необходимо передать в шаблон пустые словари errors и user, в котором необходимо задать значения по умолчанию для соответствующих полей формы. Так в шаблоне не придется выполнять проверку данных формы на существование:</p>
26
<p>Обратите внимание, как форма увеличилась в размерах. На практике она будет еще больше из-за дополнительного оформления, например, отступов и подсветки ошибок. Когда удастся сделать десяток форм, станет очевидно, что это усложнит работу. Ради простейшей обработки придется писать много практически идентичного кода в HTML. Эта работа требует автоматизации.</p>
26
<p>Обратите внимание, как форма увеличилась в размерах. На практике она будет еще больше из-за дополнительного оформления, например, отступов и подсветки ошибок. Когда удастся сделать десяток форм, станет очевидно, что это усложнит работу. Ради простейшей обработки придется писать много практически идентичного кода в HTML. Эта работа требует автоматизации.</p>
27
<p>Чтобы генерировать формы, используют специальные<strong>билдеры</strong>. Обычно у микрофреймворков нет встроенных билдеров, поэтому придется искать их самостоятельно.</p>
27
<p>Чтобы генерировать формы, используют специальные<strong>билдеры</strong>. Обычно у микрофреймворков нет встроенных билдеров, поэтому придется искать их самостоятельно.</p>
28
<p>Популярным расширением для Flask является<a>WTForms</a>. В этом компоненте каждая форма представлена собственным классом. Компонент поддерживает валидацию, имеет встроенные механизмы защиты от некоторых атак и многое другое.</p>
28
<p>Популярным расширением для Flask является<a>WTForms</a>. В этом компоненте каждая форма представлена собственным классом. Компонент поддерживает валидацию, имеет встроенные механизмы защиты от некоторых атак и многое другое.</p>
29
<h2>Заключение</h2>
29
<h2>Заключение</h2>
30
<p>Мы узнали как добавить модифицирующую форму. Сперва необходимо создать обработчики для вывода и обработки формы. Также все введеные данные необходимо валидировать прежде чем сохранять в базу данных. Наконец, нужно добавить саму HTML-форму с нужными полями и выводом ошибок.</p>
30
<p>Мы узнали как добавить модифицирующую форму. Сперва необходимо создать обработчики для вывода и обработки формы. Также все введеные данные необходимо валидировать прежде чем сохранять в базу данных. Наконец, нужно добавить саму HTML-форму с нужными полями и выводом ошибок.</p>