• Flask 学习33.FlaskRESTful 请求参数校验reqparse.RequestParser() 上海


    前言

    接口请求参数的校验是个大的工作量,参数比较少的时候还可以一个个去判断,参数多了写起来就很麻烦了。

    reqparse 解析请求参数

    尽管 Flask 能够简单地访问请求数据(比如查询字符串或者 POST 表单编码的数据),验证表单数据仍然很痛苦。Flask-RESTful 内置了支持验证请求数据,它使用了一个类似 argparse 的库。

    from flask.ext.restful import reqparse
    
    parser = reqparse.RequestParser()
    parser.add_argument('rate', type=int, help='Rate to charge for this resource')
    args = parser.parse_args()
    

    需要注意地是与 argparse 模块不同,reqparse.RequestParser.parse_args() 返回一个 Python 字典而不是一个自定义的数据结构。

    使用 reqparse 模块同样可以自由地提供聪明的错误信息。如果参数没有通过验证,Flask-RESTful 将会以一个 400 错误请求以及高亮的错误信息回应。

    $ curl -d 'rate=foo' http://127.0.0.1:5000/
    {'status': 400, 'message': 'foo cannot be converted to int'}
    

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

    args = parser.parse_args(strict=True)
    

    json 参数校验示例

    restful-full 开发的接口,一般传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
    
    {
        "message": {
            "password": "password is required"
        }
    }
    

    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"
        }
    }
    

    required=True 必需的参数

    如果这个参数是必选项,那么只需要添加 required=True 来调用 add_argument()

     parser.add_argument('username', required=True, type=str, help='username is required')
    

    多个值&列表

    如果你要接受一个键有多个值的话,你可以传入 action='append'

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

    你的参数将会像这样

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

    其它目标(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 解析值。
    在 add_argument() 中使用 location 参数可以指定解析参数的位置。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', type=str, location='headers')
    
    # From http cookies
    parser.add_argument('session_id', type=str, location='cookies')
    
    # From file uploads
    parser.add_argument('picture', type=werkzeug.datastructures.FileStorage, location='files')
    

    多个位置

    通过传入一个列表到 location 中可以指定 多个 参数位置:

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

    列表中最后一个优先出现在结果集中。(例如:location=[‘headers’, ‘values’],解析后 ‘values’ 的结果会在 ‘headers’ 前面)

    继承解析

    往往你会为你编写的每个资源编写不同的解析器。这样做的问题就是如果解析器具有共同的参数。
    不是重写,你可以编写一个包含所有共享参数的父解析器接着使用 copy() 扩充它。你也可以使用 replace_argument() 覆盖父级的任何参数,或者使用 remove_argument() 完全删除参数。
    例如:

    from flask.ext.restful import RequestParser
    
    parser = RequestParser()
    parser.add_argument('foo', type=int)
    
    parser_copy = parser.copy()
    parser_copy.add_argument('bar', type=int)
    
    # parser_copy has both 'foo' and 'bar'
    
    parser_copy.replace_argument('foo', type=str, required=True, location='json')
    # 'foo' is now a required str located in json, not an int as defined
    #  by original parser
    
    parser_copy.remove_argument('foo')
    # parser_copy no longer has 'foo' argument
    
  • 相关阅读:
    Windows Server 2008安装Memcached笔记
    解决powerDesinger12逆向工程报错:Unable to list the tables
    冒泡排序算法
    ASP.NET面试题(推荐_有答案)
    ASP.NET服务器控件分类简介
    将excel文件中的数据导入导出至SQL数据库中(Microsoft.Jet.OLEDB.4.0和Microsoft.ACE.OLEDB.12.0|office2003和office2007)
    关于sql access excel以及在web.config中数据库连接字符串的写法
    ODBC / OLEDB___DAO / RDO / ADO
    什么是CSV格式文档
    AppSettings和ConnectionStrings的区别
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/16647485.html
Copyright © 2020-2023  润新知