Flask项目(四) 使用Flask-WTForms进行表单验证

flask-wtf

它的作用就是验证数据

查看安装的包


pip freeze

(一) 安装


pipenv install flask-wtf

pip install wtforms[email]

(二) 写基类(基类支持 JSON 和 POST 请求,其余不支持)

  • 新建一个文件起名叫 FlaskFormBasic

# coding=utf-8

from flask import request
from wtforms import Form
import json
# request data 基础验证器
class RequestBaseForm(Form):
    # 解析请求参数
    def __init__(self,customdata):
        # todo 做个处理,如果请求进来的请求时form参数则else,如果是json则进行下列操作
        if "application/json" in request.headers.get("Content-Type"):
            print(customdata.to_dict())
            data = customdata.to_dict() or request.get_json(silent=True)
            args = request.args.to_dict()
            super(RequestBaseForm, self).__init__(data=data, **args)
        else:
            # application/x-www-form-urlencoded    or    multipart/form-data
            print(customdata.to_dict())
            data = customdata.to_dict() or request.form.to_dict()
            args = request.args.to_dict()
            super(RequestBaseForm, self).__init__(data=data, **args)

    # 对验证错误的参数抛出异常
    def validate_for_api(self):
            print(super(RequestBaseForm, self))
            valid = super(RequestBaseForm, self).validate()
            print("---------------------")
            if not valid:
                  # form errors
                  msg = {'code':400,'result':self.errors}
                  return msg
            return True




(三) 自定义验证

  • Email:验证上传的数据是否为邮箱

  • EqualTo:验证上传的数据是否和另一个字段相等

  • InputRequired:原始数据的需要验证,如果不是特殊情况,应该使用 InputRequired,即指定这个字段必须是要传的,否则会报错

  • Length:长度限制

  • NumberRange:数字的区间

  • Regexp:自定义正则表达式

  • URL:必须要是 url 的形式

  • UUID:验证 uuid


# coding utf-8#
#-----------------------------------------------
# Name: form
# Description
# Author: 雾烟云
# Date: 2020/8/7 0007
from FlaskFormBasic import RequestBaseForm
from wtforms import StringField,PasswordField,IntegerField,DateField
from wtforms.validators import DataRequired, Length, Email, NumberRange, EqualTo,ValidationError
from flask_wtf.file import FileField,FileAllowed
import re
class RegisterForm(RequestBaseForm):
    #表单控件要是text 就用StringField
    # username 名称不能改变 这是前端发送过来的数据
    avatar = FileField(validators=[DataRequired(message="文件必传"),FileAllowed(['jpg'],message="只能是jpg")])
    username = StringField(validators=[DataRequired(message="用户名不能为空"),Length(6,10,message="用户长度在6到10个之间!")])
    password = PasswordField(validators=[DataRequired(message="密码不能为空"),Length(3,8,message="密码长度在3到8个之间!")])
    resetpassword = PasswordField(validators=[DataRequired(message="密码不能为空"),Length(3,8,message="密码长度在3到8个之间!"),EqualTo("password")])
    email = StringField(validators=[Email()])
    age = IntegerField(validators=[DataRequired(message="年龄不能为空"),NumberRange(1, 120, message='年龄范围错误')])
    user_birthday = DateField(validators=[DataRequired(message="请输入用户生日")])
    phone = IntegerField(validators=[DataRequired(message="手机号不能为空")])
    def validate_phone(self, field):
        pattern = re.compile(r'^1[3456789]\d{9}')
        print(field.data)
        result = bool(re.search(pattern,str(field.data)))
        print(type(result))
        if result:
            return True
        else :
            raise ValidationError("手机号错误")
    captcha = StringField(validators=[Length(4,4)])
    # ## 自定义验证器
    # # 假设验证码为1234 自定义captcha验证器,函数名必须以validate开头
    # # 所以在验证captcha的时候,除了验证Length,还会调用下面自定义的函数进行验证
    def validate_captcha(self,field):   # 针对具体的字段做验证
        # 通过field.data获取数据
        if field.data == "1234":
            return "验证成功"
        else:
            raise ValidationError("验证码错误")

(四) 使用的时候


# coding utf-8#
#-----------------------------------------------
# Name: app
# Description
# Author: 雾烟云
# Date: 2020/8/7 0007

from flask import Flask,request,jsonify
from werkzeug.utils import secure_filename
from werkzeug.datastructures import CombinedMultiDict
from form import RegisterForm

app = Flask(__name__)

@app.route("/upload",methods=["POST"])
def upload():
    print(CombinedMultiDict([request.form,request.files]))
    formvalidate = RegisterForm(CombinedMultiDict([request.form,request.files])) # 将文件与文件信息都传给form
    print(formvalidate)
    if formvalidate.validate_for_api() == True:
        # 接受用户上传的数据
        print("寄哪里了")
        avatar = request.files.get("avatar")  # 获取上传文件
        print(avatar)
        # 保存文件
        file_name = secure_filename(avatar.filename)  # 对文件名进行安全检测
        avatar.save("uploaded/" + file_name)
        return "文件上传成功"+"用户的邮箱是"+request.form['email']
    else:
        return jsonify(formvalidate.validate_for_api())

if __name__=="__main__":
    app.run(host="127.0.0.1",debug=True,port=5000)

最后结果返回错误信息


{
  "code": 400,
  "result": {
    "captcha": [
      "密码必须是4位",
      "验证码错误"
    ],
    "password": [
      "密码长度在3到8个之间!"
    ],
    "phone": [
      "Invalid input."
    ],
    "resetpassword": [
      "密码不能为空"
    ],
    "user_birthday": [
      "请输入用户生日"
    ],
    "username": [
      "用户长度在6到10个之间!"
    ]
  }
}

文章作者: 雾烟云
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 雾烟云 !
  目录