介绍
wtforms是一个支持多个web框架的form组件,主要用来做表单的验证以及生成的,
安装
pip install wtforms
使用
自定义一个类,继承wtforms.Form类,定义字段
from wtforms import Form from wtforms.fields import simple,core,html5 # 字段来自于这里 from wtforms import validators # 验证规则来自于这里 from wtforms import widgets # 工具是在这里 class LoginForm(Form): user = simple.StringField( label='用户名', # 提示信息 validators=[validators.DataRequired(message='用户名不能为空.')], #验证规则的列表 widget=widgets.TextInput(), # 优先按他定义的方式渲染input标签 render_kw={'class': 'form-control'} # 为input标签设置属性 )
渲染
实例自定义的类对象,传入模板中,如果实例对象时传入了数据,该数据会被渲染到input框里
{{ form.name }} # 该字段的input框 {{ form.name.label }} # 该字段提示信息 {{ form.name.errors[0] }} # 该字段的错误信息,建议用这种方式,下面那种获取字段的错误信息会抛出异常 {{ form.errors }} # 全部的错误信息 # 也可以使用for循环的方式,并且他的顺序不会错乱,因为Form内部维持了一个计数器 {% for item in form %} <p>{{item.label}}: {{item}} {{item.errors[0] }}</p> {% endfor %}
验证
实例自定义类对象是传递数据
form = LoginForm(formdata=request.form) if form.validate(): # 验证通过,打印数据 print(form.data) else: print(form.error) # 打印错误信息
实例化时可传递的几种数据
formdata : request.data这种有get和get_list的 data : 一个字典 obj : obj.字段名获得数据的,比如模型类对象
字段
在wtforms.fields提供了三个包simple,core,html5
simple是简单常用的包括:
['BooleanField', 'TextAreaField', 'PasswordField', 'FileField', 'HiddenField', 'SubmitField', 'TextField']
core是不太常用的
( 'BooleanField', 'DecimalField', 'DateField', 'DateTimeField', 'FieldList', 'FloatField', 'FormField', 'IntegerField', 'RadioField', 'SelectField', 'SelectMultipleField', 'StringField', )
html5中的标签自带正则(浏览器校验)
( 'DateField', 'DateTimeField', 'DateTimeLocalField', 'DecimalField', 'DecimalRangeField', 'EmailField', 'IntegerField', 'IntegerRangeField', 'SearchField', 'TelField', 'URLField', )
这里要注意的是core.RadioField(单选),core.SelectField(下拉菜单),core.SelectMultipleField(多选下拉菜单)有一个coerce属性,指定了数据转化的类型(因为从前端获取到的都是字符串),如果没有转化成对应的数据类型就会验证失败.
另外如果我们想要动态的获取choices的值,可以通过在自己写的类中重写__init__方法.每次实例化的时候去获去一次,再执行父类中的__init__就可以实时更新选项了
class RegisterForm(Form): city = core.SelectField( label='城市', choices=SQLHelper.fetch_all('select id,name from city',{},None), coerce=int ) def __init__(self, *args, **kwargs): super(RegisterForm, self).__init__(*args, **kwargs) self.city.choices = PymysqlConn.fetch_all('select id,name from city',{},None)
验证规则
在wtforms.validators中提供了许多的验证规则
( 'DataRequired', 'data_required', 'Email', 'email', 'EqualTo', 'equal_to', 'IPAddress', 'ip_address', 'InputRequired', 'input_required', 'Length', 'length', 'NumberRange', 'number_range', 'Optional', 'optional', 'Required', 'required', 'Regexp', 'regexp', 'URL', 'url', 'AnyOf', 'any_of', 'NoneOf', 'none_of', 'MacAddress', 'mac_address', 'UUID' )
下面介绍几个常用的
DataRequired:非空验证,message=错误信息
Email:邮箱格式验证,message=错误信息
Length: 长度验证,min=最短,max=最长,message=错误信息
Regexp: 正则匹配,regex正则表达式,message=错误信息
EqualTo:与其他字段的值比较是否相同,fieldname=其他字段名,message=错误信息
自定义验证-钩子
# 为一个字段设置验证 def validate_字段名(self, field): print(field.data) # 当前字段传过来的值 print(self.data) # 当前传过来的所有的值:name,gender..... if 验证失败: raise validators.ValidationError("继续后续验证") # raise validators.StopValidation("不再继续后续验证")
小部件
wtforms.widgets提供了许多的表单样式,每个字段都有默认的widget,通过设置widget可以修改渲染出来的样式
('CheckboxInput', 'FileInput', 'HiddenInput', 'ListWidget', 'PasswordInput', 'RadioInput', 'Select', 'SubmitInput', 'TableWidget', 'TextArea', 'TextInput', 'Option')
多选框的设置
favor = core.SelectMultipleField( label='喜好', choices=( (1, '篮球'), (2, '足球'), ), widget=widgets.ListWidget(prefix_label=False), option_widget=widgets.CheckboxInput(), coerce=int, default=[1, 2] )