Формирование валидации с 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 unicode, поэтому нам нужно сообщить Jinja2, что эти данные уже экранированы с помощью |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–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/1.0.x/patterns/wtforms/