使用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 )。 但是 这并非必要的,请按照您的需要修正代码。
注意事项:
- create the form from the request
form
value if the data is submitted via the HTTPPOST
method andargs
if the data is submitted asGET
. - 要验证数据,请调用
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 %}
这些宏接受一对键值对,WTForms 的字段函数接收这个宏然后为我们渲染他们。 关键字参数将作为HTML属性插入。因此,例如,您可以调用render_field(form.username, class ='username')
以向输入元素添加类。注意,WTForms返回标准的Python unicode字符串,所以我们必须告诉Jinja2这个数据已经使用|safe
过滤器进行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网站。