【问题标题】:Simple request parsing without reqparse.RequestParser()没有 reqparse.RequestParser() 的简单请求解析
【发布时间】:2020-07-29 07:33:53
【问题描述】:

flask_restful.reqparse 已被弃用 (https://flask-restful.readthedocs.io/en/latest/reqparse.html):

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

我对 Marshmallow 进行了简要的研究,但如果我想替换 reqparse.RequestParser(),我仍然对如何使用它感到有些困惑。我们会写什么,而不是像下面这样:

from flask import Flask, request, Response
from flask_restful import reqparse

@app.route('/', methods=['GET'])
def my_api() -> Response:
   parser = reqparse.RequestParser()
   parser.add_argument('username', type=str, required=True)
   args = parser.parse_args()
   return {'message': 'cool'}, 200

(又看了半个小时的文档……)

RequestParser默认看MultiDictrequest.values(显然是查询参数,然后根据https://stackoverflow.com/a/16664376/5139284形成body参数)。那么我们只需要以某种方式验证request.values 中的数据即可。

这是 Marshmallow 中一些相关代码的 sn-p。它似乎比reqparse 更复杂:首先创建一个模式类,然后实例化它,然后让它加载请求 JSON。我宁愿不必为每个 API 端点编写单独的类。有没有更轻量级的类似于reqparse,可以在定义端点的函数中写入所有类型的参数验证信息?

from flask import Flask, request, Response
from flask_restful import reqparse
from marshmallow import (
    Schema,
    fields,
    validate,
    pre_load,
    post_dump,
    post_load,
    ValidationError,
)

class UserSchema(Schema):
    id = fields.Int(dump_only=True)
    email = fields.Str(
        required=True, validate=validate.Email(error="Not a valid email address")
    )
    password = fields.Str(
        required=True, validate=[validate.Length(min=6, max=36)], load_only=True
    )
    joined_on = fields.DateTime(dump_only=True)

user_schema = UserSchema()

@app.route("/register", methods=["POST"])
def register():
    json_input = request.get_json()
    try:
        data = user_schema.load(json_input)
    except ValidationError as err:
        return {"errors": err.messages}, 422
    # etc.

【问题讨论】:

    标签: python flask flask-restful


    【解决方案1】:

    如果您的端点在架构中有任何共同点,您可以使用 fields.Nested() 将定义嵌套在每个 Marshmallow 类中,这样可以节省每个端点的代码编写。 Docs are here.

    例如,对于更新名为“用户”的资源的操作,您可能需要用户信息的标准化子集来执行操作,例如 user_id、user_login_status、user_authorisation_level 等。这些可以创建一次并嵌套在新的用于更具体的用户操作的类,例如更新用户帐户:

    class UserData(Schema):
        user_id = fields.Int(required=True)
        user_login_status = fields.Boolean(required=True)
        user_authentication_level = fields.Int(required=True)
        # etc ....
    
    class UserAccountUpdate(Schema):
        created_date = fields.DateTime(required=True)
        user_data = fields.Nested(UserData)
        # account update fields...
    
    

    【讨论】:

      猜你喜欢
      • 2023-01-10
      • 1970-01-01
      • 2018-04-23
      • 2012-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      相关资源
      最近更新 更多