Flask 数据校验

683 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情

在web应用当中,大多数的情况是从数据库当中获取数据渲染到页面上,但是也有从前端获取数据传递到服务端的过程,表单就是最长用的一种策略,但是如果百分之百的相信前端传递的数据,那么绝对会出问题所以就有了后端的数据校验。

WTForm表单校验

三方提供了flask-WTForm进行表单校验,极大的简化了表单校验的流程,当然WTForm也可以实现前端表单样式的渲染,但是由于前后端分离和前端表单样式的多样化,我们在这里就不多赘述了,只是研究一下WTFrom的后端校验能力。

pip install flask_wtf

校验整体分为个步骤:

1、定义校验数据类,这里的定义方式有点类似与上面聊过的ORM类的定义方式,定义的类除了可以作为校验使用,还可以用在前端渲染,会自动渲染出HTML表单样式。

2、定义校验规则,校验规则定义在第一步类的属性当中。

3、发起校验,在视图当中获取提交的数据进行校验。

#导入表单类
from flask_wtf import FlaskForm
#导入字段类
from wtforms import StringField,PasswordField
#导入校验
from wtforms.validators import DataRequired,Length,Regexp
class LoginForm(FlaskForm):
    '''
    这些字段对象会被渲染为html标签
    实例化一个文本字段对象,设置参数
    label:这个值可以拿出来放在标签前面显示
    validators=[]验证器列表,实例化的验证器对象,里面又可以设置参数
​
    '''
    #用户名字段
    username = StringField(
        label='用户名',
        validators=[
            DataRequired(message='用户名不能为空'),
            Length(3,20,message='用户名长度在3-20个字符')
        ] #校验部分
    )
​
    password = PasswordField(
        label='密码',
        validators=[
            DataRequired(message='密码不能为空'),
            Length(3,20,message='密码长度在3-20个字符'),
            Regexp(r'^[a-z0-9A-Z]+$',message='密码只能有字母,数字,下划线组成')
        ] #校验部分
    )
​

视图:

from flask import Flask
from flask import request
from flask import redirect
from flask import render_template
app = Flask(__name__)
​
@app.route("/login",methods=["GET","POST"])
def login():
    if request.method == "POST":
        form_data = LoginForm(formdata=request.form) #接受前端的参数
        if form_data.validate(): #开始校验,并且通过
            return redirect("/index")
        else: #如果没有通过,错误会集中到form_data.errors当中
            return render_template("login.html",errors = form_data.errors)
​
if __name__ == "__main__":
    app.run(debug=True)

表单字段

和ORM类一样,数据校验类也需要定义字段,不同的字段对类型有校验,并且前端渲染的表单格式也是不一样的。

字段名称字段类型
StringField字符串
IntegerField数字
RadioField单选框
BooleanField复选框
SelectField下拉框
TextAreaField文本域
DateField日期类型

内置校验

flask-wtform也提供了部分定义好的校验类,存放在wtforms.validators当中,使用的时候只要调用就可以了

校验方法描述
Length字符串长度限制,有min和max两个值进行限制。
EqualTo验证数据是否和另外一个字段相等,常用的就是密码和确认密码两个字段是否相等。
Email验证上传的数据是否为邮箱数据格式 如:laobian@qq.com
InputRequired验证该项数据为必填项,即要求该项非空。
NumberRange数值的区间,有min和max两个值限制,如果处在这两个数字之间则满足。
Regexp定义正则表达式进行验证,如验证手机号码,这个使用最舒服。
URL必须是URL的形式 比如:juejin.cn/

自定义校验

尽管插件提供了很多校验的方法,但实际工作当中还是有很多校验是满足不了的,不如用户名重复校验,那么就需要自定义校验,wtForm自定义校验可以分为两种:

1、表单类当中,定义以validate_字段名称为名字的方法,只对当前表单指定字段生效的自定义校验方法。

#导入表单类
from flask_wtf import FlaskForm
#导入字段类
from wtforms import StringField,PasswordField
from wtforms.validators import ValidationError
​
class LoginForm(FlaskForm):
    #用户名字段
    username = StringField(label='用户名')
    password = PasswordField(label='密码')
    
    #名字必须是validate_username才可以自动校验username
    def validate_username(self,value):  
        #这里的value就是接收到的字段值
        if len(value) < 8:
            raise ValidationError('验证码不一致')
        return value
​

2、定义自定义校验函数,可以在整个文件当中使用。

#导入表单类
from flask_wtf import FlaskForm
#导入字段类
from wtforms import StringField,PasswordField
from wtforms.validators import ValidationError
​
def validate_username(value):
    #这里的value就是接收到的字段值
        if len(value) < 8:
            raise ValidationError('验证码不一致')
        return value
    
class LoginForm(FlaskForm):
    #用户名字段
    username = StringField(label='用户名',validators=[validate_username])
    password = PasswordField(label='密码')