【问题标题】:Make Flask Marshmallow NestedSchema work wtth my API route使 Flask Marshmallow 嵌套模式与我的 API 路由一起使用
【发布时间】:2020-06-17 10:52:59
【问题描述】:

我正在使用 Flask、SQLAlchemy 和 Marshmallow 制作 API。

模型被定义,数据库被数据填充,当视图被点击时。我从 NonProfitSchema 获取所有字段 JSON 内容。

class NonprofitSchema(ma.ModelSchema):
    class Meta:
        model = Nonprofit

        # To specialize fields something like so
        fields = ('id', 'name', 'ein', 'ico', 'street', 'city', 'state', 'zipcode', 'group', 'subsection', 'affiliation', 'classification', 'ruling',
 'deductability', 'foundation', 'activity', 'organization', 'status', 'tax_period', 'asset_cd','income_cd', 'filing_req_cd', 'pf_filing_req_cd',
 'acct_pd', 'asset_amt', 'income_amt', 'revenue_amt', 'ntee', 'sort_name', 'activity_full')

我试图从中创建一个新架构,并仅返回数据的子集,如下所示

class AddressSchema(NonProfitSchema):

    from marshmallow import fields 
    address = fields.Nested(NonprofitSchema(only=("street", "city", "state", "zipcode",)))  

我的 view.py 中的路线是这样设置的:

@api_blueprint.route("/api/orgs/id/<int:id>/", methods=["GET"]) def get_org_by_id(id):
    org = Nonprofit.query.get(id)
    return npschema.jsonify(org)

@api_blueprint.route("/api/orgs/address/<int:id>/", methods=["GET"]) def get_org_by_id_address(id):
    org = Nonprofit.query.get(id)
    return addyschema.jsonify(org)

但是,在浏览器中访问它们时。它们都返回完全相同的东西,即NonprofitSchema的整个数据库模型

我认为不可能使用 Schema 处理数据子集,对吧?

【问题讨论】:

  • 您应该指定您使用的棉花糖版本。

标签: python flask sqlalchemy marshmallow


【解决方案1】:

或者,您可以将此逻辑直接插入到 jsonify 步骤中

org = Nonprofit.query.get(id)
only_these_fields = ["street", "city", "state", "zipcode"]
return addyschema.jsonify({key: value for key, value in org.items() if key in only_these_fields}

【讨论】:

  • 是的,我在想这可能是我自己唯一的出路。我正在等待任何其他方法,但如果没有,我将尽可能接受并继续。
  • 我知道那种感觉。我讨厌像 Marshmallow 这样的包裹使事情变得更复杂而不是更容易。确实应该有更好的方法,但我不明白为什么您的解决方案也不起作用。也许要等几天让棉花糖专家出现
【解决方案2】:

我没有全貌,但我觉得将父模式嵌套在子模式中很奇怪。

这个怎么样(未经测试)?

class AddressSchema(NonProfitSchema):

    class Meta:
        fields = ("street", "city", "state", "zipcode",)

【讨论】:

    【解决方案3】:

    我应该更新我的答案。虽然我和用户 c8999c 3f964f64 基本上是这样想的,而且确实可以。在我的情况下,对象上的“jsonify”不起作用,因为在他的示例中我构建了一个单独的函数,因为没有 items 属性。因此,使用 get 属性的过滤器如下:

    def jsonfilter(obj, attrlist):
    
        resp = {}
        for attr in attrlist:
            resp[attr] = getattr(obj,attr)
        return resp
    

    然后修改函数以便使用它:

    @api_blueprint.route("/api/orgs/id/<int:id>/address", methods=["GET"])
    def get_org_address_by_id(id):
        org = Nonprofit.query.get(id)
        only_these_fields = ["id", "ein", "name", "street", "city", "state", "zipcode"]
        return jsonify(jsonfilter(org, only_these_fields))
    

    我能够让它工作。

    在查看 Flask 和 Flask-Marshmallow 文档后,另一种更简单的方法是简单地实例化一个带有传入字段的模型的新类对象。

    @api_blueprint.route("/api/orgs/id/<int:id>/address", methods=["GET"])
    def get_org_address_by_id(id):
        org = Nonprofit.query.get(id)
        only_these_fields = ["id", "ein", "name", "street", "city", "state", "zipcode"]
        addyschema = NonprofitSchema(fields=only_these_fields)
        return addyschema.jsonify(org)
    

    我选择不使用这种方法,因为我更喜欢只需要一个单独的类对象,并且调用过滤器方法感觉更好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 2018-07-14
      • 2021-10-19
      • 2019-01-30
      相关资源
      最近更新 更多