1、flask-WTF简介
Flask-WTF是简化了WTForms操作的一个第三方库。WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板。当然还包括一些其他的功能:CSRF保护,文件上传等。安装Flask-WTF默认也会安装WTForms。
pip install flask-wtf —user
2、表单验证
1、在主入口文件中写入”简单的表单验证”
templates文件夹中的view1.html文件
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Verification</title></head><body>{% macro input(name, value="", type="text") %}<input name="{{ name }}", value="{{ value }}", type="{{ type }}">{% endmacro %}<form action="" method="post"><!-- 表单提交到flask中 -->用户名:{{ input("username") }}<br>密码:{{ input("password") }}<br>确认密码:{{ input("password_repate") }}<br>{{ input(value="注册", type="submit") }}</form></body></html>
主入口文件:
from flask import Flask, request, render_templateapp = Flask(__name__)app.config["TEMPLATES_AUTO_RELOAD"] = True@app.route('/')def home():return "首页"@app.route('/cation/', methods=["GET", "POST"])def verification():if request.method == "GET":return render_template("view1.html")else:username = request.form.get("username")password = request.form.get("password")password_repate = request.form.get("password_repate")if len(username) < 3 or len(username) > 10:return "用户名长度非法"if len(password) < 3 or len(password) > 10:return "密码长度非法"if password != password_repate:return "密码和确认密码不一致"if __name__ == '__main__':app.run(debug=True)
这样的写法与业务逻辑无关,并且显得代码非常冗余,这里只需要返回判断的结果即可,所以下面使用flask-wtf进行操作
2、通过wtforms进行表单验证
templates文件夹中的view1.html文件,不进行改变
新建forms.py文件
from wtforms import Form, StringField, validatorsfrom wtforms.validators import Length, Regexp, EqualTo# 表单验证,继承Form类class RegistForm(Form):# if len(username) < 3 or len(username) > 10:# return "用户名长度非法"username = StringField(validators=[Length(min=3, max=10)])# if len(password) < 3 or len(password) > 10:# return "密码长度非法"password = StringField(validators=[Length(min=3, max=10)])# if password != password_repate:# return "密码和确认密码不一致"password_repate = StringField(validators=[Length(min=3, max=10), EqualTo("password")])
代码注解:
from wtforms import Form, StringField, validators# Form类用于继承# StringField表示字段,用于接收# validators验证器用来写各种验证种类from wtforms.validators import Length, Regexp, EqualTo# 导入验证的种类
注意点:
username = StringField(validators=[Length(min=3, max=10)])
用户名:{{ input(name="username") }}<br>
注意名称的一致性!!!
验证的种类有:
__all__ = ('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','ValidationError', 'StopValidation')
主入口文件
from flask import Flask, request, render_template# 从定义的forms.py文件中导入RegistFormfrom forms import RegistFormapp = Flask(__name__)app.config["TEMPLATES_AUTO_RELOAD"] = True@app.route('/')def home():return "首页"@app.route('/cation/', methods=["GET", "POST"])def verification():# 判断:如果是是GET请求if request.method == "GET":return render_template("view1.html")else:form = RegistForm(request.form)# form.validate()判断是否通过表单请求if form.validate():return "验证通过"else:# 返回验证的错误信息print(form.errors)return "验证失败"if __name__ == '__main__':app.run(debug=True)
在网页中输入输入:
返回值:

返回值是英文值,如何修改返回值,通过修改验证中的message参数
class RegistForm(Form):username = StringField(validators=[Length(min=3, max=10, message="非法的用户名长度")])password = StringField(validators=[Length(min=3, max=10, message="非法的密码长度")])password_repate = StringField(validators=[Length(min=3, max=10), EqualTo("password", message="两次输入不一致")])
3、常用的验证器
支持自己写(正则),都有message参数,可以叠加(如有特殊需求,可以修改原码)
# EqualTo 判断两者是否相等password_confirm = StringField(validators=[EqualTo("想要相等的变量名或者值")])# Length 限制长度username = StringField(validators=[Length(min=3, max=10)])# Email 判断是否为邮箱格式# 需要安装额外支持pip install email-validator --useremail = StringField(validators=[Email()])# NumberRange 给定一个数值范围# 使用的不是StringField而是IntegerField或者其他数字的字段age = IntegerField(validators=[NumberRange(1,120))# InputRequired 字段必须要填写name = StringField(validators=[InputRequired()])# Regexp 写正则表达式# 输入手机号phone_number = StringField(validators=[Regexp(r"1[358]/d{9}")])# URL 判断网址格式url = StringField(validators=[URL()])
小例子:验证码(可以自己定义方法,但是要注意命名)
class CaptchaForm(Form):# 验证码captcha = StringField(validators=[Length(min=4, max=4, message="请检查输入长度")])# 这里的写法要注意必须是validate_ + 需要验证的字段print(type(captcha))# 写法必须是validate_ + 需要验证的字段def validate_captcha(self, field):# 这里把验证码写死# print(field.data)# <class 'wtforms.fields.core.UnboundField'> , 为什么是field, 原因大概在这# 通过field.data可以获取出对应的值if field.data != "1234":# 主动抛出异常raise ValidationError("验证失败")
3、知识点-form模板渲染
form可以渲染模板,减少一定的代码量,下面对forms.py文件进行改写
class RegistForm(Form):username = StringField("用户名", validators=[Length(min=3, max=10)])password = StringField("密码", validators=[Length(min=3, max=10)])password_repate = StringField("确认密码", validators=[Length(min=3, max=10), EqualTo("password")])
增加一个位置参数,用来在html文件中,做标签起到提示作用
将主入口文件进行相应的修改
@app.route('/cation/', methods=["GET", "POST"])def verification():# 判断:如果是是GET请求if request.method == "GET":return render_template("view1.html")else:form = RegistForm(request.form)# form.validate()判断是否通过表单请求if form.validate():# 保存数据至数据库中user = User(name=form.username.data, password=form.password.data)db.session.add(user)db.session.commit()# 打印相关的信息print(form.username.label)print(form.username())# 渲染到前端, 并传入表单数据return render_template("view1.html", form=form)else:# 返回验证的错误信息print(form.errors)return "验证失败"

通过传入form变量,在模板中可以使用表单form变量了 return render_template(“view1.html”, form=form)
增加新的模板文件(由于定义了宏,所以下面就只能开新得模板了,流下能力不够的泪水)
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Verification</title></head><body><form action="" method="post"><table><tr><td>{{ form.username.label }}</td><td>{{ form.username() }}</td></tr><tr><td>{{ form.password.label }}</td><td>{{ form.password() }}</td></tr><tr><td></td><td><input type="submit" value="提交"></td></tr></table></form></body></html>

