flask-WTF是对WTForms的再封装,使其更好更方便地适用于flask框架。WTForms表单的两个主要功能是验证用户提交数据的合法性和渲染模板,至于渲染模板这个功能由于前后端分离的开发模式而变得有些鸡肋。
安装:pip3 install flask-WTF
安装flask-WTF的时候也会自动把WTForms也安装了。
对于表单验证,如注册表单,要输入用户名,密码,重复密码,而且有很多规则限制,如长度,必须字母开头且包含数字字母下划线中的两种或以上等等,这时候就得在后端做很多逻辑判断,比较烦杂。WTForms可以帮我们来处理验证问题。
以下是登录注册过程的表单验证处理:
app.py:
1 from flask import Flask,request,render_template 2 from forms_verify import RegisterForm,LoginForm 3 app = Flask(__name__) 4 5 @app.route('/') 6 def hello_world(): 7 return "hello world" 8 9 @app.route('/register',methods=['GET','POST']) 10 def register(): 11 if request.method == "GET": 12 return render_template('register.html') 13 else: 14 form = RegisterForm(request.form) 15 if form.validate(): 16 return "注册成功!!" 17 else: 18 return return_err_message('register.html',form) 19 20 21 @app.route('/login',methods=['GET','POST']) 22 def login(): 23 if request.method == "GET": 24 return render_template('login.html') 25 else: 26 form = LoginForm(request.form) 27 if form.validate(): 28 return "登录成功!!" 29 else: 30 return return_err_message('login.html',form) 31 32 33 def return_err_message(template,form): 34 ''' 将返回错误提示信息功能抽离出来单独作为一个函数''' 35 print(form.errors) 36 err_message = list(form.errors.values())[0][0] # 错误信息的字符串提取 37 print(err_message) 38 content = { 39 'err_message': err_message 40 } 41 return render_template(template, **content) 42 43 44 if __name__ == '__main__': 45 app.run()
forms_verify.py :表单验证
1 from wtforms import Form,StringField,IntegerField,FileField 2 from wtforms.validators import ValidationError,Length,EqualTo,Email,InputRequired,Regexp,NumberRange,URL,UUID 3 from flask_wtf.file import FileRequired,FileAllowed 4 5 """ 表单验证 """ 6 7 class RegisterForm(Form): # 继承自Form 8 """注册表单验证""" 9 email = StringField(validators=[Email(message="邮箱格式不正确")])# message:错误提示信息 10 # validators:验证器,可多个,列表形式表示 11 username = StringField(validators=[InputRequired(message="您未输入")]) 12 pwd = StringField(validators=[Length(min=6, max=12, message="密码长度必须为6至12位")]) 13 pwd_rep = StringField(validators=[EqualTo('pwd',message="两次密码输入必须一致")]) 14 age = IntegerField(validators=[NumberRange(12, 120,message="年龄超出范围")]) 15 phone = StringField(validators=[Regexp(r'1(3[0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|8[0-9]|9[89])d{8}',message="手机号格式不正确"), 16 Length(min=11, max=11, message="手机号格式不正确")]) 17 homepage = StringField(validators=[URL(message="url格式不正确")]) 18 uuid = StringField(validators=[UUID(message="uuid格式不正确")]) 19 20 class LoginForm(Form): 21 """ 登录表单验证 """ 22 username = StringField(validators=[Length(min=6, max=12, message="用户名长度必须为6至12位")]) 23 pwd = StringField(validators=[Length(min=6, max=12, message="密码长度必须为6至12位")]) 24 25 captcha = StringField(validators=[Length(4,4,message="验证码错误")]) 26 def validate_captcha(self,filed): 27 """这里方法名必须validate_字段名,假设验证码为9850""" 28 if filed.data != "9850": 29 raise ValidationError("验证码错误")
常用的验证器:
1. Email:验证上传的数据是否为邮箱。
2. EqualTo:验证上传的数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等。
3. InputRequir:验证输入是否为空。
3. Length:长度限制,有min和max两个值进行限制。
4. NumberRange:数字的区间,有min和max两个值限制,如果处在这两个数字之间则满足。
5. Regexp:自定义正则表达式。
6. URL:必须要是URL的形式。
7. UUID:验证UUID。
login.html:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>login</title> 6 </head> 7 <body> 8 <form action="" method="post"> 9 <table> 10 <tr> 11 <td>用户名:</td> 12 <td><input type="text" name="username"></td> 13 </tr> 14 <tr> 15 <td>密码:</td> 16 <td><input type="password" name="pwd"></td> 17 </tr> 18 <tr> 19 <td>验证码:</td> 20 <td><input type="text" name="captcha"></td> 21 </tr> 22 <tr> 23 <td></td> 24 <td><input type="submit" value="立即登录"></td> 25 </tr> 26 </table> 27 {% if err_message %} 28 <p style="color: red">{{ err_message }}</p> 29 {% endif %} 30 </form> 31 </body> 32 </html>
register.html:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>register</title> 6 </head> 7 <body> 8 <form action="" method="post"> 9 <table> 10 <tr> 11 <td>邮箱:</td> 12 <td><input type="text" name="email"></td> 13 </tr> 14 <tr> 15 <td>用户名:</td> 16 <td><input type="text" name="username"></td> 17 </tr> 18 <tr> 19 <td>密码:</td> 20 <td><input type="password" name="pwd"></td> 21 </tr> 22 <tr> 23 <td>重复密码:</td> 24 <td><input type="password" name="pwd_rep"></td> 25 </tr> 26 <tr> 27 <td>年龄:</td> 28 <td><input type="text" name="age"></td> 29 </tr> 30 <tr> 31 <td>手机号:</td> 32 <td><input type="text" name="phone"></td> 33 </tr> 34 <tr> 35 <td>主页:</td> 36 <td><input type="text" name="homepage"></td> 37 </tr> 38 <tr> 39 <td>UUID:</td> 40 <td><input type="text" name="uuid"></td> 41 </tr> 42 <tr> 43 <td></td> 44 <td><input type="submit" value="立即注册"></td> 45 </tr> 46 </table> 47 {% if err_message %} 48 <p style="color: red">{{ err_message }}</p> 49 {% endif %} 50 </form> 51 </body> 52 </html>
实际页面:
自定义验证器:
如果想要对表单中的某个字段进行更细化的验证,那么可以针对这个字段进行单独的验证。如验证码,步骤如下:
1. 定义一个方法,方法的名字规则是:'validate_字段名(self,filed)'。
2. 在方法中,使用'field.data'可以获取到这个字段的具体的值。
3. 如果数据满足条件,那么可以什么都不做。如果验证失败,那么应该抛出一个'wtforms.validators.ValidationError'的异常,并且把验证失败的信息传到这个异常类中。