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属性,指定了数据转化的类型(因为从前端获取到的都是字符串),如果没有转化成对应的数据类型就会验证失败.