Flask Restful:向GET请求传递参数

64

我想创建一个支持以下GET请求方式的资源:

/bar?key1=val1&key2=val2

我尝试了这段代码,但它没有起作用

app = Flask(__name__)
api = Api(app)

class BarAPI(Resource):
    def get(key1, key2):
        return jsonify(dict(data=[key1, key2]))

api.add_resource(BarAPI, '/bar', endpoint='bar')

谢谢!


2
你提出问题后已经过了一段时间,而你选择的答案使用了一个已经被弃用的API。能否更新接受的答案? - Stereo
确实,有一个更好的库叫做flask_restful,你可以在其中定义资源(对数据库的'钩子',定义CRUD操作),将它们添加到API中,并使用蓝图将该API绑定到Flask上。在其中,您将找到RequestParser类,用于解析作为文档主体传递的参数。 - OzzyTheGiant
4个回答

61

编辑:reqparse不再是使用flask-restful的推荐方法!但是下面有另一个使用marshmallow的例子。

reqparse对象已过时。请参阅文档或此文章中的第二个示例以获取其他替代方案。


使用reqparse。在flask-restful 文档中还可以看到另一个示例。

它对参数执行验证并且不需要jsonify

from flask import Flask
from flask_restful import Resource, Api, reqparse

app = Flask(__name__)
api = Api(app)

class BarAPI(Resource):
    def get(self):

        parser = reqparse.RequestParser()
        parser.add_argument('key1', type=str)
        parser.add_argument('key2', type=str)

        return parser.parse_args()

api.add_resource(BarAPI, '/bar', endpoint='bar')

if __name__ == '__main__':
    app.run(debug=True)

另一种方法是使用marshmallow

您可以使用Schema类来验证request.args(对于PUT / POST请求,您可能会验证request.form

from flask import Flask, request, abort
from flask_restful import Resource, Api
from marshmallow import Schema, fields


class BarQuerySchema(Schema):
    key1 = fields.Str(required=True)
    key2 = fields.Str(required=True)

app = Flask(__name__)
api = Api(app)
schema = BarQuerySchema()


class BarAPI(Resource):
    def get(self):
        errors = schema.validate(request.args)
        if errors:
            abort(400, str(errors))

        return 'ok'

api.add_resource(BarAPI, '/bar', endpoint='bar')

# omit of you intend to use `flask run` command
if __name__ == '__main__':
    app.run(debug=True)

这个例子要求两个参数都必须存在。


54

Flask 可以通过请求解析参数。

from flask import request

您可以在需要GET参数的块中使用以下代码行。 GET在@app.route()声明中声明。

args = request.args
print (args) # For debugging
no1 = args['key1']
no2 = args['key2']
return jsonify(dict(data=[no1, no2])) # or whatever is required

2
虽然 Flask 的请求对象使得获取 GET 参数变得容易,但它并不执行数据验证。更好的方式是使用类似于 marshmallow 或者 webargs(由 marshmallow 的作者创建)的对象数据映射器来进行数据验证和过滤,以确保应用程序安全性。 - Devy
3
处理查询未传递的情况的更好方式是:request.args.get('key1', DEFAULT_COUNT, type=int) - May Noppadol

39

由于reqparse已被弃用,这里使用WebArgs库提供解决方案:

from flask import Flask
from flask_restful import Api, Resource, abort
from webargs import fields, validate
from webargs.flaskparser import use_kwargs, parser

app = Flask(__name__)
api = Api(app)

class Foo(Resource):
    args = {
        'bar': fields.Str(
            required=True,
            validate=validate.OneOf(['baz', 'qux']),
        ),
    }

    @use_kwargs(args)
    def get(self, bar):
        return {'bar': bar}

api.add_resource(Foo, '/foo', endpoint='foo')

# This error handler is necessary for usage with Flask-RESTful.
@parser.error_handler
def handle_request_parsing_error(err, req, schema, *, error_status_code, error_headers):
    abort(error_status_code, errors=err.messages)

if __name__ == '__main__':
    app.run(debug=True)

更多示例请参见WebArgs存储库中的Flask-RESTful示例


0

@severen的答案是2016年的,关于webargs有点过时了。据我所知,在2020年的主要更新版本6.0.0中,装饰器默认查看json有效载荷并忽略查询参数。要添加此提示,请将location="query"添加到装饰器中(请参见github issue)。

以上面的示例为例,接受GET请求的工作端点应如下所示:

class Foo(Resource):
    @use_kwargs({"bar": fields.Str(), }, location="query")
    def get(self, bar):
        return {'message': 'Hello, ' + bar}, 200

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接