Формирование формы с помощью WTForms
При работе с данными форм, отправляемыми браузером, код быстро становится трудночитаемым. Существуют библиотеки, предназначенные для упрощения этого процесса. Одна из них — WTForms, которую мы рассмотрим здесь. Если у вас много форм, стоит попробовать ее.
При работе с WTForms сначала нужно определить формы как классы. Я рекомендую разбить приложение на несколько модулей (Большие приложения как пакеты) для этого и добавить отдельный модуль для форм.
Максимальное использование WTForms с расширением
Расширение Flask-WTF расширяет эту модель и добавляет несколько небольших помощников, которые делают работу с формами и Flask более приятной. Вы можете получить его из PyPI.
Формы
Это пример формы для типичной страницы регистрации:
from wtforms import Form, BooleanField, StringField, PasswordField, validators
class RegistrationForm(Form):
username = StringField('Username', [validators.Length(min=4, max=25)])
email = StringField('Email Address', [validators.Length(min=6, max=35)])
password = PasswordField('New Password', [
validators.DataRequired(),
validators.EqualTo('confirm', message='Passwords must match')
])
confirm = PasswordField('Repeat Password')
accept_tos = BooleanField('I accept the TOS', [validators.DataRequired()])
В представлении
В функции представления использование этой формы выглядит так:
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
user = User(form.username.data, form.email.data,
form.password.data)
db_session.add(user)
flash('Thanks for registering')
return redirect(url_for('login'))
return render_template('register.html', form=form)
Обратите внимание, что здесь подразумевается, что представление использует SQLAlchemy (SQLAlchemy в Flask), но это, конечно, не обязательно. Измените код по мере необходимости.
Следует помнить:
- создайте форму из запроса
formзначение, если данные отправлены с помощью HTTPPOSTметода иargsесли данные отправлены какGET. - для проверки данных вызовите метод
validate(), который вернётTrueесли данные пройдут валидацию,Falseв противном случае. - для доступа к отдельным значениям из формы, обратитесь к
form.<NAME>.data.
Формы в шаблонах
Теперь о стороне шаблонов. Когда вы передаете форму в шаблоны, вы можете легко отобразить ее там. Посмотрите на следующий пример шаблона, чтобы увидеть, насколько это просто. WTForms уже выполняет половину генерации форм за нас. Чтобы сделать его еще приятнее, мы можем написать макрос, который отображает поле с меткой и списком ошибок, если они есть.
Вот пример _formhelpers.html шаблона с таким макросом:
{% macro render_field(field) %}
<dt>{{ field.label }}
<dd>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</dd>
{% endmacro %}
Этот макрос принимает несколько именованных аргументов, которые передаются функции поля WTForm, которая отображает поле для нас. Именованные аргументы будут вставлены как атрибуты HTML. Например, вы можете вызвать render_field(form.username, class='username') чтобы добавить класс к элементу ввода. Обратите внимание, что WTForms возвращает стандартные строки Python, поэтому мы должны сказать Jinja2, что эти данные уже обработаны с использованием HTML-экранирования с помощью фильтра |safe.
Вот register.html шаблон для функции, которую мы использовали выше, который использует _formhelpers.html шаблон:
{% from "_formhelpers.html" import render_field %}
<form method=post>
<dl>
{{ render_field(form.username) }}
{{ render_field(form.email) }}
{{ render_field(form.password) }}
{{ render_field(form.confirm) }}
{{ render_field(form.accept_tos) }}
</dl>
<p><input type=submit value=Register>
</form>
Для получения дополнительной информации о WTForms перейдите на сайт WTForms.
© 2007–2021 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.0.x/patterns/wtforms/