禁止 flask_restful reqparse 对请求中未设置的参数自动填充为 None

时间:2021-02-03 14:44:00 来源:互联网 作者: 神秘的大神 字体:

问题

使用 flask_restful 编写 RESTFUL 接口,使用其中的 reqparse 进行参数解析时,一般按下面这样使用的

from flask_restful import Resource, reqparse

class Scans(Resource):
    def __init__(self):
        timemode_choices = ('-T0', '-T1', '-T2', '-T3', '-T4', '-T5')

        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('name', type=str, location='json')
        self.reqparse.add_argument('port', type=str, location='json')
        self.reqparse.add_argument('timemode', type=str, location='json', choices=timemode_choices)

        super(Scans, self).__init__()

    def post(self):
        args = self.reqparse.parse_args()
        print(args)
        return args

    def get(self):
        pass

像上面这样使用时,在请求中没有设置的参数会被默认设置为 None。如下图所示,分别是演示的打印的终端输出和返回响应中的输出。
打印的终端输出
返回的响应输出
但是,有时候我们可能并不想要为未设置的参数设置默认None值,仅仅是想解析手动设置的参数,然后传递给其他的程序或命令。

解决方法

将 parser.args 中的各个参数的 store_missing 设置为 False。具体的方法就是添加一个 prepare_args_for_parser(parser) 函数,专门用来设置各个参数的store_missing=False. 修改后代码如下。

from flask_restful import Resource, reqparse

# new
def prepare_args_for_parser(parser):
    """ Modifies all the args of a Parser to better defaults. """
    if not isinstance(parser, reqparse.RequestParser):
        raise ValueError('Expecting a parser')
    for arg in parser.args:
        arg.store_missing = False
        arg.help = "Error: {error_msg}. Field description: %s" % arg.help
    return parser

class Scans(Resource):
    def __init__(self):
        timemode_choices = ('-T0', '-T1', '-T2', '-T3', '-T4', '-T5')

        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument('name', type=str, location='json')
        self.reqparse.add_argument('port', type=str, location='json')
        self.reqparse.add_argument('timemode', type=str, location='json', choices=timemode_choices)

        # new
        self.reqparse = prepare_args_for_parser(self.reqparse)

        super(Scans, self).__init__()

    def post(self):
        args = self.reqparse.parse_args()
        print(args)
        return args

    def get(self):
        pass

修改后的效果

修改后打印的终端输出
修改后返回的响应输出
可以看到没有在请求中设置的 port 和 timemode 参数,没有被默认设置为 None。

参考

https://github.com/flask-restful/flask-restful/issues/610
http://www.pythondoc.com/Flask-RESTful/reqparse.html#id2