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_template
app = 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, validators
from 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文件中导入RegistForm
from forms import RegistForm
app = 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 --user
email = 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>