在Web程序中,表单是和用户交互最常见的方式。用户注册、登陆、写文章、编辑设置等等,都要用到表单。表单的处理包括了创建表单、验证用户输入内容、错误提示、获取和保存数据。我们可以通过WTForms--一个用Python编写的表单库 来解决这些问题。
HTML表单
Html中通过<form>标签创建表单,表单中的字段用<input>标签定义,<label>标签用来定义字段的标签文字。
WTForms支持在Python中使用类定义表单,然后通过类定义生成HTML代码。这种方式更加简便而且易于重用,所以我们一般不直接在模板中直接使用HTML编写表单。
定义WTForms表单类
安装flask-wtf库后在Python shell中写如下代码
PyDev console: starting.
Python 3.6.6 |Anaconda custom (64-bit)| (default, Jun 28 2018, 11:27:44) [MSC v.1900 64 bit (AMD64)] on win32
from wtforms import *
from wtforms.validators import *
class LoginForm(Form):
username = StringField('username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)])
remrember = BooleanField('Remember me')
submit = SubmitField('Log in')
实例化表单类,然后将实例属性转换为字符串或者直接调用就可以获取表单字段对应的HTML代码。
form = LoginForm()
form.username()
'<input id="username" name="username" required type="text" value="">'
常用WTForms字段如下:
字段类型
BooleanField 复选框,值为Ture或False
DateField 文本字段,值会被处理成datetime.date对象
DateTimeField 文本字段,值会被处理成datetiem.datetime对象
FileField 文件上传字段
FloatField 浮点数字段
IntegerField 整型字段
RadioField 一组单选按钮
SelectField 下拉列表
SelectMultipleField 多选下拉列表
SubmitField 提交按钮
StringField 文本字段
HiddenField 隐藏文本字段
PasswordField 密码文本字段
TextAreaField 多行文本字段
验证器
验证器是用于验证字段数据的类,在实例化字段类时用validators关键字来指定附加的验证器列表。验证器从wtforms.validators模块中导入。
常用的WTForms验证器如下
DataRequired 验证数据是否有效
Email 验证Email格式
EqualTo 验证两个字段是否相同
InputRequired 验证是否有数据
Length 验证输入长度是否在给定范围以内
NumberRange 验证输入数字是否在给定范围内
Optional 允许输入为空并且跳过其他验证
Regexp 使用正则表达式验证输入值
URL 验证URL
AnyOf 确保输入值在可选值列表中
NoneOf 确保输入值在不可选列表中
输出HTML代码
在创建HTML表单时,我们经常需要使用<input>标签的其他属性来设置字段。比如添加class来设置CSS类型,添加placeholder来在输入框内显示文字等等。默认情况下,WTForms输出的字段HTML代码只包含id和name属性,属性值均为表单类中对应的字段属性名称,要添加其他属性,有以下两种方法:
1.使用render_kw属性
用render_kw属性设置placeholder属性
username = StringField('username', render_kw={'placeholder':'Your Username'})
输出HTML代码(这是在新写的LoginForm2里写的)
>>> LoginForm2().username()
'<input id="username" name="username" placeholder="Your Username" type="text" value="">'
2.在调用字段时传入
在调用字段属性时,同过添加括号使用关键字参数的心事也可以传入字段额外的HTML属性
>>>form.username(style='width: 20px',class_='bar')
'<input class="bar" id="username" name="username" required style="width: 20px" type="text" value="">'
需要注意的是因为class是Python中的关键字,在设置标签的class属性时用的是class_。
通过这种方法也可以修改id的值。但是name的属性值不能修改,因为表单被提交后,WTForms需要通过name属性值来获取对应数据所以不能修改name属性值。
在模板中渲染表单
首先,在视图函数里实例化表单类,然后再render_template()函数中使用关键字参数form将表单实例传入模板。
在app.py中写好视图函数并传入表单
@app.route('/basic') def basic(): form = LoginForm() return render_template('login.html', form=form)
forms.py文件内容
from flask_wtf import FlaskForm from wtforms import * from wtforms.validators import DataRequired, Length class LoginForm(FlaskForm): username = StringField('username', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired(), Length(8, 128)]) remember = BooleanField('Remember me') submit = SubmitField('Log in')
在模板(basic.html)中调用表单类的属性获取对应HTML代码。
<form method="post"> {{ form.csrf_token }} {{ form.username.label }}{{ form.username(placeholder='Your Name') }}<br> {{ form.password.label }}{{ form.password }}<br> {{ form.remember }}{{ form.remember.label }}<br> {{ form.submit }}<br> </form>
运行结果