flask中的WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据的验证
安装: pip3 install wtforms
我们现在使用WTForms写一个注册登录的验证
flask代码部分:
from flask import Flask, render_template,request from wtforms.fields import simple, core # 字段来源 from wtforms import validators # 验证规则 from wtforms import Form # 导入form需要继承 app = Flask(__name__) # 登录验证 class LoginForm(Form): username = simple.StringField( label="用户名", # 标签标记 validators=[validators.DataRequired(message="用户名不能为空"), validators.Length(min=3,max=8,message="不是长了就是短了")], # 校验条件 可迭代条件 # description='11111111111', # 描述标记 id="user_id", # 标签ID default=None, # 默认值 widget=None, # 优先按他定义的方式渲染input标签 render_kw={"class":"my_login"}, # 为标签设置属性 {"class":"my_login"} ) password = simple.PasswordField( label="密码", # 标签标记 validators=[validators.DataRequired(message="密码不能为空"), validators.Length(min=3, max=16, message="不是长了就是短了"), validators.Email(message="密码必须符合邮箱规则")], # 不知道 # description='11111111111', # 描述标记 id="user_id", # 标签ID default=None, # 默认值 widget=None, # 默认组件(input type="text") 在StringField中已经被实例化了 render_kw={"class": "my_login"}, # {"class":"my_login"} ) # 注册验证 class RegForm(Form): username = simple.StringField( label="用户名", # 标签标记 validators=[validators.DataRequired(message="用户名不能为空"), validators.Length(min=3,max=8,message="用户名不是长了就是短了")], # 校验条件 可迭代条件 ) password = simple.PasswordField( label="密码", # 标签标记 validators=[validators.DataRequired(message="密码不能为空"), validators.Length(min=3, max=16, message="密码不是长了就是短了"), validators.Email(message="密码必须符合邮箱规则")], ) repassword = simple.PasswordField( label="确认密码", # 标签标记 validators=[validators.EqualTo(fieldname="password",message="眼神未确认")] ) gender = core.RadioField( label="性别", coerce=str, choices=( ("1","女"), ("2","男") ), default="1" ) hobby = core.SelectMultipleField( label="爱好", validators=[validators.Length(min=2,max=4,message="癖好有问题")], coerce=int, choices=( (1, "fengjie"), (2, "luoyufeng"), (3, "lixueqin"), (4, "wuyifan"), (5, "panta") ), default=(1,3,5) ) # 登录视图 @app.route("/",methods=["GET","POST"]) def index(): if request.method == "GET": fm = LoginForm() return render_template("index.html",wtf = fm) else: new_fm = LoginForm(request.form) if new_fm.validate(): return new_fm.data.get("password") else: return render_template("index.html", wtf=new_fm) # 注册页面 @app.route("/reg",methods=["GET","POST"]) def reg(): if request.method == "GET": rf = RegForm() return render_template("reg.html",rf = rf) else: rf = RegForm(request.form) if rf.validate(): print(type(rf.data.get("gender")),rf.data.get("gender")) return rf.data.get("password") else: return render_template("reg.html", rf=rf) if __name__ == '__main__': app.run(debug=True) app.__call__
前端代码部分:
index.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form action="" method="post" novalidate> {{ wtf.username.label }} {{ wtf.username }} <p><h1>{{wtf.username.errors.0}}</h1></p> <p> {{ wtf.password.label }} {{ wtf.password }} </p> <p><h1>{{wtf.password.errors.0}}</h1></p> <input type="submit" value="登录"> </form> </body> </html>
registe注册页面:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <form action="" method="post" novalidate> {% for field in rf %} <p>{{ field.label }}{{ field }}{{ field.errors.0 }}</p> {% endfor %} <input type="submit" value="注册"> </form> </body> </html>
上面我们已经简单的实现了一个注册登录的验证,下面我们看一下WTForms中常用的验证规则:
DataRequired:非空验证,message=错误信息
Email:邮箱格式验证,message=错误信息
Length: 长度验证,min=最短,max=最长,message=错误信息
Regexp: 正则匹配,regex正则表达式,message=错误信息
EqualTo:与其他字段的值比较是否相同,fieldname=其他字段名,message=错误信息
字段:
在wtforms.fields提供了三个包simple,core,html5
simple是简单常用的包括:
1
2
|
[ 'BooleanField' , 'TextAreaField' , 'PasswordField' , 'FileField' , 'HiddenField' , 'SubmitField' , 'TextField' ] |
core是不太常用的
1
2
3
4
5
|
( 'BooleanField' , 'DecimalField' , 'DateField' , 'DateTimeField' , 'FieldList' , 'FloatField' , 'FormField' , 'IntegerField' , 'RadioField' , 'SelectField' , 'SelectMultipleField' , 'StringField' , ) |
html5中的标签自带正则(浏览器校验)
1
2
3
4
5
|
( 'DateField' , 'DateTimeField' , 'DateTimeLocalField' , 'DecimalField' , 'DecimalRangeField' , 'EmailField' , 'IntegerField' , 'IntegerRangeField' , 'SearchField' , 'TelField' , 'URLField' , ) |
这里要注意的是core.RadioField(单选),core.SelectField(下拉菜单),core.SelectMultipleField(多选下拉菜单)有一个coerce属性,指定了数据转化的类型(因为从前端获取到的都是字符串),如果没有转化成对应的数据类型就会验证失败.