【问题标题】:What is the difference in configuring the end points using app.route() and api.add_resource() in a Python Flask application?在 Python Flask 应用程序中使用 app.route() 和 api.add_resource() 配置端点有什么区别?
【发布时间】:2020-10-29 03:30:25
【问题描述】:

我正在学习 Python-Flask,发现有两种方法可以在应用程序中创建端点。

1. app.routing(/endpoint)
2. api.add_resource(CLASSNAME, endpoint)

使用app.routing(),我们可以在方法上添加一个端点并调用它。使用api.add_resource(),我们需要注册类名和端点。

如果您使用的是api.add_resource(),我已经看到方法名称为get() & put() 例如:

app = Flask(__name__)
api = Api(app)
vehicles = []

class VehicleData(Resource):    
    parser = reqparse.RequestParser()
    parser.add_argument('vehicle', type=str, required=True, help='name cannot be empty')
    parser.add_argument('type', type=str, required=True, help='vehicle type cannot be empty')
    parser.add_argument('wheels', type=int, required=True, help='number of wheels cannot be empty')
    parser.add_argument('suv', type=bool, required=False, help='SUV or not can be empty')

    def get(self, name):
        vehicle = next(filter(lambda x: x['name'] == name, vehicles), None)
        return {'vehicle': vehicle}, 200 if vehicle else 404

    def post(self, name):
        # data = request.get_json()
        # sport.append({'sportname': data['sport_name'], 'team_size':data['team_size'], 'popularity':data['popularity']})
        if next(filter(lambda x: x['name'] == name, vehicles), None) is not None:
            print("in the IF BLOCK")
            return {'message': 'The vehicle {n} already exists in the database'.format(n=name)}, 404

        v_data = VehicleData.parser.parse_args()
        vehicle = {'name': name, 'type':v_data['type'],  'vehicle': v_data['vehicle'], 'suv': v_data['suv'], 'wheels': v_data['wheels']}
        vehicles.append(vehicle)
        return vehicle, 201

    def getallvehicles(self):
        return {'vehicles': vehicles}

api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>')
app.run(port=5000, debug=True)

如果我通过 GET http 调用提交 API http://127.0.0.1:5000/getvehicle,我将按照代码中给出的逻辑正确获取数据。在代码中,我只有一个 GET & POST 方法。因此,当我使用 GET 请求提交 http://127.0.0.1:5000/getvehicle/&lt;name&gt; 时,Flask 会自动调用 get()

如果我的方法名称不是 get()/post()/put() 怎么办? 例如,如果我有一个返回所有车辆的方法getallvehicles(),即返回列表vehicles,我如何在api.register() 中注册它?

例如,我试过这个:

api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>', '/getallvehicles')

并使用 GET 请求提交 API 调用“http://127.0.0.1:5000/getallvehicles”,我遇到了错误:

 File "/Users/bobby/PyCharmProjects/FlaskAPI/venv/lib/python3.7/site-packages/flask_restful/__init__.py", line 583, in dispatch_request
    resp = meth(*args, **kwargs)
TypeError: get() missing 1 required positional argument: 'name'

谁能告诉我我在这里犯了什么错误以及如何在下面的行中为getallvehicles() 提供一个端点并将其映射到GET http 请求:

api.add_resource(VehicleData, '/addvehicle/<string:name>', '/getvehicle/<string:name>', '/getallvehicles')

【问题讨论】:

  • 在 flask_restful 中,方法名被固定为 http 方法(get、post、put、patch 和 delete),因此它们可以根据请求方法自动映射。我认为您在这里要做的是定义一个名为VehicleList 的新类,其get() 返回所有车辆。
  • 我已经尝试过了,它可以工作。但是有没有其他方法可以避免使用新类?
  • 简短的回答是“不”。 flask_restful 框架是为解决 REST 约定而构建的。您尝试做的事情不符合 REST。

标签: python flask flask-restful


【解决方案1】:

两种不同方式的区别在于:

这是一种“本机”烧瓶方法,您可以使用它来包装您的函数。

@app.routing('/endpoint')

这是 restfull_flask 包的一部分,它以不同于原生烧瓶方式的方式做事。

api.add_resource(CLASSNAME, endpoint)

你可以用这两种方法做同样的事情,但是如果你使用rest_framework,那么你应该使用第二种方法:)

对于您的其他问题,我相信您会在本文档中找到答案: https://flask-restful.readthedocs.io/en/latest/

【讨论】:

  • 但我无法在我解释过的其余框架中实现相同的功能。你能给我在api.add_resource(VehicleData, '/addvehicle/&lt;string:name&gt;', '/getvehicle/&lt;string:name&gt;', '/getallvehicles') 行中添加方法getallvehicles 的语法吗?这就是我面临错误的地方。
  • 检查我添加到答案的链接:)
  • stackoverflow.com/a/52322815/12868928 我认为这篇文章回答了你的问题
猜你喜欢
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 2017-05-02
  • 2011-08-10
  • 2016-08-12
  • 1970-01-01
  • 2010-10-17
  • 2015-10-01
相关资源
最近更新 更多