快速入门
1. 创建表单
Flask-WTF 提供了对 WTForms 的集成。例如:
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
class MyForm(Form):
name = StringField('name', validators=[DataRequired()])
我们把上诉定义 form 的代码放入名为 forms.py 的文件中。
2. 在模板中渲染表单
我们先来定义视图函数,记得把之前定义的 MyForm 引入了。
from myapp.forms import MyForm
@app.route('/')
def index():
return render_template(
'index.html',
form = MyForm()
)
在模板中渲染:
<form method="POST" action="/">
{{ form.csrf_token }}
{{ form.name.label }} {{ form.name(size=20) }}
<input type="submit" value="Go">
</form>
3.验证表单
在你的视图处理程序中验证请求:
@app.route('/submit', methods=('GET', 'POST'))
def submit():
form = MyForm()
if form.validate_on_submit():
return '验证通过!'
return '验证未通过!'
你不需要把 request.form 传给 Flask-WTF;Flask-WTF 会自动加载。便捷的方法 validate_on_submit() 将会检查是否是一个 POST 请求并且请求是否有效。
在这里我们用了验证器 DataRequired,它要求这个字段不能为空。
form 的属性与方法
参加:https://wtforms.readthedocs.io/en/stable/forms.html#the-form-class
属性
-
data
返回一个包含表单数据的字典,如果我们想单独获取某字段,可以form.<字段名>.data。 -
errors
返回一个包含每个字段错误信息的字典,必须先执行form.validate()验证后才会生成,未验证或没有错误则返回空字典。 -
meta
用于使用元类。
方法
-
validate()
验证数据是否通过校验。 -
populate_obj(obj)
用表单的数据修改某实例的属性。比如一个修改 user 资料的例子:
def edit_profile(request):
user = User.objects.get(pk=request.session['userid'])
form = EditProfileForm(request.POST, obj=user)
if request.POST and form.validate():
form.populate_obj(user)
user.save()
return redirect('/home')
return render_to_response('edit_profile.html', form=form)
字段验证器
参加:https://wtforms.readthedocs.io/en/stable/forms.html#in-line-validators
我们可以通过创建名为 validate_ + 字段名 的函数来自定义某个字段的验证。例如:
class SignupForm(Form):
age = IntegerField(u'Age')
def validate_age(form, field):
if field.data < 13:
raise ValidationError("We're sorry, you must be 13 or older to register")
wtforms 字段参数
参加:https://wtforms.readthedocs.io/en/stable/fields.html#wtforms.fields.Field
-
label
字段的名称 -
validators
字段要用到的验证器 -
filters
字段要用到的过滤器 -
description
字段的描述,通常用于帮助文本 -
id
在前端渲染表单时生成的 id -
default
前端渲染表单时生成的 input 的默认值 -
Widgets
窗口小部件,改变字段在前端表单的渲染形式。例如,某个字段想用TextArea形式:
from wtforms.widgets import TextArea
class MyForm(FlaskForm):
name = StringField(
label = 'name',
widget = TextArea()
)
详情见:https://wtforms.readthedocs.io/en/stable/widgets.html
- render_kw
参数格式为字典,在前端渲染表单时提供额外的属性,比如某一个 input 我想设定为placeholder="姓名":
class MyForm(FlaskForm):
name = StringField(
label = 'name',
render_kw = {'placeholder': '姓名'}
)
wtforms 字段类型
参见:https://wtforms.readthedocs.io/en/stable/fields.html#basic-fields
-
BooleanField
生成<input type =“checkbox”>,使用default = "checked"会将默认选项设置为 True。 -
DateField
对应datetime.date的数据类型。 -
DateTimeField
对应datetime.datetime数据类型。 -
DecimalField
处理带小数的数字类型。 -
FileField
处理文件类型 -
MultipleFileField
处理多个文件的类型 -
FloatField
浮点数类型 -
IntegerField
整数类型 -
RadioField
前端渲染成选项类型(radio),例如:
# 后端定义
sex = RadioField(
label = 'sex',
choices = [('male','男'), ('female','女')]
)
# 前端渲染
{% for subfield in form.work %}
<tr>
<td>{{ subfield }}</td>
<td>{{ subfield.label }}</td>
</tr>
{% endfor %}
-
SelectField
-
SelectMultipleField
-
SubmitField
-
StringField
-
HiddenField
-
PasswordField
-
TextAreaField
内置验证器
参见:https://wtforms.readthedocs.io/en/stable/validators.html#wtforms.validators.DataRequired
-
DataRequired
-
Email
-
EqualTo
检验两个字段是否相等,一个验证两次密码输入是否一致的例子:
class MyForm(FlaskForm):
password1 = StringField(
label = '密码:',
validators = [
InputRequired(message='请输入密码'),
EqualTo('password2', message='两次密码输入不一致')
],
)
password2 = StringField(
label = '再次输入密码:',
validators = [InputRequired(message='请输入密码')]
)
-
InputRequired
-
IPAddress
-
Length
参数:min、max表示最小和最大长度;message表示错误信息 -
MacAddress
-
NumberRange
验证数值的最大和最小值,整数、浮点数都有效;参数:min、max和message -
Optional
使用后允许空输入 -
Regexp
正则表达式 -
URL
-
UUID
-
AnyOf
把输入数据和某个值比较(输入的数据必须为某值) -
NoneOf
把输入数据和某个值比较(输入的数据不能为某值)
自定义验证器
参见:https://wtforms.readthedocs.io/en/stable/validators.html#custom-validators
一个例子,自定义一个验证器,检验 name 字段的输入长度。
class MyForm(Form):
name = StringField('Name', [InputRequired()])
def validate_name(form, field):
if len(field.data) > 50:
raise ValidationError('Name must be less than 50 characters')
也可以单独用一个函数作为验证器,这样该验证器就能重复使用:
def my_length_check(form, field):
if len(field.data) > 50:
raise ValidationError('Field must be less than 50 characters')
class MyForm(Form):
name = StringField('Name', [InputRequired(), my_length_check])
还可以编写更复杂的验证器,比如带参数的验证器:
def length(min=-1, max=-1):
message = 'Must be between %d and %d characters long.' % (min, max)
def _length(form, field):
l = field.data and len(field.data) or 0
if l < min or max != -1 and l > max:
raise ValidationError(message)
return _length
class MyForm(Form):
name = StringField('Name', [InputRequired(), length(max=50)])
为了更好代码重用,可以包装成类:
class Length(object):
def __init__(self, min=-1, max=-1, message=None):
self.min = min
self.max = max
if not message:
message = u'Field must be between %i and %i characters long.' % (min, max)
self.message = message
def __call__(self, form, field):
l = field.data and len(field.data) or 0
if l < self.min or self.max != -1 and l > self.max:
raise ValidationError(self.message)
length = Length(min=1, max=5)
class MyForm(FlaskForm):
work = StringField(
label = 'work',
validators = [
InputRequired(),
length
]
)









网友评论