Flask 学习-44.Flask-RESTX 请求参数校验reqparse.RequestParser()

尉迟龙光
2023-12-01

前言

Flask-RESTX 的整个请求解析器部分将被删除,并将被有关如何与其他可以更好地执行输入/输出内容的包(例如 marshmallow)集成的文档所取代。
这意味着它将保持到 2.0,但认为它已被弃用。不用担心,如果您现在有代码使用它并希望继续这样做,它不会很快消失。

reqparse 解析请求参数

这是请求解析器的一个简单示例。它在flask.Request.values字典中查找两个参数:一个整数和一个字符串

from flask_restx import reqparse

parser = reqparse.RequestParser()
parser.add_argument('rate', type=int, help='Rate cannot be converted')
parser.add_argument('name')
args = parser.parse_args()

add_argument()默认参数类型是 unicode 字符串, type=str

如果您指定该help值,则在解析时引发类型错误时,它将呈现为错误消息。如果您未指定帮助消息,则默认行为是从类型错误本身返回消息

笔记
默认情况下,请求参数是非必填(required=False)。此外,请求中提供的不属于 的参数RequestParser将被忽略。
在请求解析器中声明但未在请求本身中设置的参数将默认为None.

使用 strict=True 调用 parse_args 能够确保当请求包含你的解析器中未定义的参数的时候会抛出一个异常。

args = parser.parse_args(strict=True)

json 参数校验示例

Flask-RESTX 开发的接口默认传json 格式,请求头部默认带上Content-Type: application/json
在没有加 reqparse之前,通过request.get_json() 获取传过来的json数据

        # 获取入参
        data = request.get_json()
        print(f'请求入参:{args}')

使用 reqparse 获取传过来的数据,并对数据校验,视图部分代码

class Register(Resource):

    def post(self):
        # 校验入参
        parser = reqparse.RequestParser()
        parser.add_argument('username', required=True, type=str, help='username is required')
        parser.add_argument('password', required=True, type=str, help='password is required')
        args = parser.parse_args()
        print(f'请求入参:{args}')

        return jsonify({
            "code": 0,
            "msg": "success"
        })


# 注册
api.add_resource(Register, '/api/v1/register')

如果缺少请求参数, 会直接返回400 BAD REQUEST

POST http://127.0.0.1:5000/api/v1/register HTTP/1.1
User-Agent: Fiddler
Host: 127.0.0.1:5000
Content-Type: application/json
Content-Length: 29

{
    "username": "test8"
}

HTTP/1.1 400 BAD REQUEST
Server: Werkzeug/2.2.2 Python/3.8.5
Date: Thu, 01 Sep 2022 11:04:48 GMT
Content-Type: application/json
Content-Length: 70
Connection: close

HTTP/1.0 400 BAD REQUEST
Content-Type: application/json
Content-Length: 200
Server: Werkzeug/2.0.1 Python/3.8.5
Date: Sun, 04 Sep 2022 12:07:16 GMT

{
    "errors": {
        "username": "username is required Missing required parameter in the JSON body or the post body or the query string"
    },
    "message": "Input payload validation failed"
}


required=True 必填项

对add_argument()添加 required=True 那么此参数是必填项

parser.add_argument('name', required=True, help="Name cannot be blank!")

help 值

指定参数,添加help

        # 校验入参
        parser = reqparse.RequestParser()
        parser.add_argument('username', required=True, type=str, help='username is required')
        parser.add_argument('password', required=True, type=str, help='password is required')
        args = parser.parse_args()

如果你指定了 help 参数的值,在解析的时候当类型错误被触发的时候,它将会被作为错误信息给呈现出来。如果你没有指定 help 信息的话,默认行为是返回类型错误本身的信息。

正如上面接口看到的,缺少password参数,接口返回

HTTP/1.1 400 BAD REQUEST
Server: Werkzeug/2.2.2 Python/3.8.5
Date: Thu, 01 Sep 2022 11:04:48 GMT
Content-Type: application/json
Content-Length: 70
Connection: close

{
    "message": {
        "password": "password is required"
    }
}

多个值和列表

如果您想接受一个键的多个值作为列表,您可以通过action=‘append’:

parser.add_argument('name', action='append')

这将让您进行如下查询

curl http://api.example.com -d "name=bob" -d "name=sue" -d "name=joe"

你的 args 看起来像这样:

args = parser.parse_args()
args['name']    # ['bob', 'sue', 'joe']

如果您希望使用逗号分隔列表,请使用action=‘split’:

parser.add_argument('fruits', action='split')

这将让您进行如下查询

curl http://api.example.com -d "fruits=apple,lemon,cherry"

你的 args 看起来像这样:

args = parser.parse_args()
args['fruits']    # ['apple', 'lemon', 'cherry']

其它目标(Destinations)

如果由于某种原因,你想要以不同的名称存储你的参数一旦它被解析的时候,你可以使用 dest kwarg。

parser.add_argument('name', type=str, dest='public_name')

args = parser.parse_args()
args['public_name']

参数位置

默认情况下,RequestParser尝试解析来自 flask.Request.values和的值flask.Request.json。
使用location参数来add_argument() 指定从中提取值的备用位置。上的任何变量 flask.Request都可以使用。例如:

# Look only in the POST body
parser.add_argument('name', type=int, location='form')

# Look only in the querystring
parser.add_argument('PageSize', type=int, location='args')

# From the request headers
parser.add_argument('User-Agent', location='headers')

# From http cookies
parser.add_argument('session_id', location='cookies')

# From file uploads
parser.add_argument('picture', type=werkzeug.datastructures.FileStorage, location='files')

仅type=list在 时使用location=‘json’,使用location='form’是验证表单数据和记录表单字段的方法。

多个位置

可以通过将列表传递给来指定多个参数位置location:

parser.add_argument('text', location=['headers', 'values'])

当指定多个位置时,来自所有指定位置的参数将组合成一个MultiDict. 最后location列出的优先于结果集中。

如果参数位置列表包括headers 位置,则参数名称将不再区分大小写,并且必须匹配它们的标题大小写名称(请参阅 参考资料str.title())。指定 location=‘headers’(不是列表)将保持不区分大小写。

 类似资料: