使用 WTForms 进行表单验证¶
当您必须处理浏览器视图提交的表单数据时,代码很快就会变得非常难以阅读。有些库旨在使此过程更容易管理。其中之一是 WTForms,我们将在本文中对其进行处理。如果您发现自己有许多表单,则可能需要尝试一下。
当您使用 WTForms 时,您必须首先将表单定义为类。我建议为此将应用程序分解为多个模块(大型应用程序作为包),并添加一个单独的模块用于表单。
表单¶
这是典型注册页面的示例表单
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(Flask 中的 SQLAlchemy),但这当然不是必需的。根据需要调整代码。
需要记住的事项
如果数据通过 HTTP
POST
方法提交,则从请求form
值创建表单;如果数据作为GET
提交,则创建args
。要验证数据,请调用
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 字符串,因此我们必须使用 |safe
过滤器告诉 Jinja2 此数据已转义为 HTML。
以下是我们上面使用的函数的 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 网站。