首页 > 解决方案 > 没有 reqparse.RequestParser() 的简单请求解析

问题描述

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

(在阅读了更多文档半小时后……)

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

这是 Marshmallow 中一些相关代码的片段。这似乎比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.

标签: pythonflaskflask-restful

解决方案


如果您的端点在模式中有任何共同点,您可以使用 fields.Nested() 在每个 Marshmallow 类中嵌套定义,这可以节省每个端点的代码编写。文档在这里。

例如,对于更新名为“用户”的资源的操作,您可能需要用户信息的标准化子集来执行操作,例如 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...


推荐阅读