引言 在我们构建Flask_Web项目的时候,需要对客户端发送的request进行数据验证:必填?数据类型?长度限制等。除了Flask-WTF、WTForms外,笔者发现一款更好用的库pre-request,为什么说它好用(step1.简单配置rule;step2.装饰器注入到指定的Flask视图函数上)。 学习内容:

  1. 【安装】pre-request
  2. 示例演示(login接口)
  3. 语法规则

参考文档:

1.安装pre-request

  1. pipenv install pre-request

2.使用步骤

对于pre-request的使用,我们需要经历3个步骤:

  • 【step1】导入pre-request;
  • 【step2】定义验证规则;
  • 【step3】规则的使用;

    1.代码实现

    下面是对“project-add(新增项目)”接口进行添加“请求验证规则”的示例:
    image.png ```python from flask import Blueprint as bp from flask import makeresponse, request, jsonify from flask import current_app, redirect # 【核心代码】使用Flask中的current_app from sqlalchemy import or, and_ from jsonpath import jsonpath from utils.models import * from api.utils.check_login_status import check_login_status from utils.redisUtil import ops_string import json

    【核心代码】 【导入】uuid工具-函数

    from utils.optUtils import traceID from utils.responseUtil import responseUtil

【step2】 声明-蓝图—>参数:定义蓝图的名字;导入name

projectApp = bp(“projectApp”, name, url_prefix=’/api/project’)

from pre_request import pre, Rule # 导入:请求验证库(pre-request) import datetime # 用于请求验证(数据类型=时间)

【请求验证规则】

projectRule = { “projectName”: Rule(type=str, required=True), “startTime”: Rule(type=datetime.datetime, fmt=’%Y-%m-%d %H:%M:%S’, required=True), “endTime”: Rule(type=datetime.datetime, fmt=’%Y-%m-%d %H:%M:%S’, required=True, gte_key=”startTime”),

  1. # 【gte_key(即大于)】结束时间>开始时间

}

@projectApp.post(“/add”) @check_login_status @pre.catch(post=projectRule) # 视图函数-绑定-【请求验证规则=projectRule】 def addproject(): traceId = traceID() requestBody = request.get_json() try: requestToken = request.headers[‘token’] print(“requestToken:\t”, requestToken) redisOps = ops_string() requestTokenSearchInRedis = redisOps.get(requestToken) username = (json.loads(requestTokenSearchInRedis)).get(“username”) print(“token-username:\t”, username) requestBody.update(username=username) print(“requestBody:\t”, requestBody) requestBody.update(is_delete=0) projectName = requestBody[‘projectName’] resCount = Project.query.filter(Project.projectName == projectName).count() print(“resCount:\t”, resCount) if resCount == 0: project = Project(**requestBody) db.session.add(project) msg = {“code”: 0, “msg”: “项目创建成功”, “traceId”: traceId}

  1. # msg.update(data)
  2. # dictSort(data=msg) # 按照ascii升序排序
  3. response = make_response(msg)
  4. responseUtil(current_app, logLevel='info', request=request,
  5. requestBody=requestBody,
  6. response=response)
  7. return response, 200
  8. else:
  9. print("已存在相同的-项目名称")
  10. msg = {"code": 502, "msg": "项目创建失败,已存在相同的-项目名称", "traceId": traceId}
  11. response = make_response(msg)
  12. responseUtil(current_app, logLevel='error', request=request,
  13. requestBody=requestBody,
  14. response=response)
  15. return response, 502
  16. except:
  17. msg = {"code": 500, "msg": "业务API异常", "traceId": traceId}
  18. response = make_response(msg)
  19. responseUtil(current_app, logLevel='error', request=request, requestBody=requestBody,
  20. response=response)
  21. return response, 500
  22. db.session.close()

```

2.验证

前提在“project-add”接口中,我们定义“projectName、startTime、endTime”均为必填
操作 projectName不填(即projectName为空)
预期结果 reponse报错:projectName不能为空(相似的报文信息)
实际结果 “respMsg”: “‘projectName’ can’t be empty”
测试结果 测试通过(见下图)
image.png

3.定义规则(语法)

1.常用参数

前提(导包) from pre_request import pre, Rule

示例: # 【请求验证规则】
_projectRule = {
“projectName”: Rule(type=str, required=True),
“startTime”: Rule(type=datetime.datetime, fmt=‘%Y-%m-%d %H:%M:%S’, required=True),
“endTime”: Rule(type=datetime.datetime, fmt=‘%Y-%m-%d %H:%M:%S’, required=True, gte_key=“startTime”),
# 【gtekey(即大于)】结束时间>开始时间
}

参数 说明(定义) 参数值(常用)
type 数据类型
- 【str】type=str
- 【int】type=int
- 【datetime】type=datetime.datetime 【需导入:import datetime及配合fmt参数使用 】
- 【date】type=datetime.date 【需导入:import datetime及配合fmt参数使用 】
required 必填字段
- required=True【必填】
- required=False【非必填】
fmt 格式化【针对日期、时间】
- fmt=’%Y-%m-%d %H:%M:%S’ 【需配合type=datetimedatetime 或type=datetime.date使用】
gte_key 大于【即大于指定字段】
- gte_key=”startTime” 【即结束时间>开始时间】
email email规则
- email=True【开启email规则】
- email=False【关闭email规则】
reg 正则表达式
- reg=r”0?(13|14|15|17|18|19)[0-9]{9}” 【正则:手机号】
其他参数 参见官方文档 https://pre-request.readthedocs.io/en/master/intro.html