【问题标题】:Marshmallow serialize nested with parent field棉花糖序列化与父字段嵌套
【发布时间】:2018-03-27 06:04:43
【问题描述】:

抱歉,如果之前有人问过这个问题,我实际上找不到解决方案或类似问题(可能使用了错误的词)。

我正在使用 marshmallow 和 peewee 更新现有的 Flask API,该 API 从我们无法控制的客户端接收数据(无法更改 JSON 数据格式)。

数据格式是这样来的:

{
    "site_id": "0102931",
    "update_date": "2018/02/11-09:33:23",
    "updated_by": "chan1",
    "crc": "a82131cf232ff120aaf00001293f",
    "data": [{"num": 1,
              "id": "09213/12312/1",
              "chain": "chain2",
              "operator": "0000122",
              "op_name": "Fred",
              "oid": "12092109300293"
             },
             {"num": 2,
              "id": "09213/12312/2",
              "chain": "chain1",
              "operator": "0000021",
              "op_name": "Melissa",
              "oid": "8883390393"
             }]           
}

我们对主块中的任何内容都不感兴趣,而是 site_id,在反序列化以创建模型和存储数据时,必须将其复制到列表中的每个对象中。 p>

这是peeewee中的模型:

class production_item(db.Model):
   site_id = TextField(null=False)
   id_prod = TextField(null=False)
   num = SmallIntegerField(null=False)
   chain = TextField(null=False)
   operator = TextField(null=False)
   operator_name = TextField(null=True)
   order_id = TextField(null=False)

这是 marshamallow 架构:

class prodItemSchema(Schema):
    num=String(required=True)
    id=String(required=True)
    chain=String(required=True)
    operator=String(required=True)
    op_name=String(required=False, allow_none=True)
    oid=String(required=False, allow_none=True)

我找不到使用 load() 方法和 prodItemSchema 的预加载/加载后装饰器从主结构传递站点 ID 的方法,因此无法创建模型。另外,我希望 marshmallow 为我验证整个结构,而不是像他们现在在代码中那样在资源和架构之间做两部分。

但是在文档中找不到方法来制作这样的东西,这可能吗?

【问题讨论】:

  • 我不相信只有一个模式可以做到这一点。您可能需要两个模式,一个用于主要对象,一个用于“数据”,并在 pre 或在主对象的架构中发布加载挂钩。
  • 我尝试了嵌套模式,但找不到从父模式中收集 site_id 值的方法,所以我最终选择了另一种方法。我会用代码自动回答我自己的问题,这可能是一种更好的方法,但这个方法有效。

标签: flask marshmallow


【解决方案1】:

在棉花糖中,可以在序列化之前将值从父方案传递给其子方案,方法是使用父方案上的pre_dump 装饰器设置context。设置上下文后,可以使用 function field 从父级获取值。

class Parent(Schema):
    id = fields.String(required=True)
    data = fields.Nested('Child', many=True)

    @pre_dump
    def set_context(self, parent, **kwargs):
        self.context['site_id'] = parent['id']
        return data

class Child(Schema):
    site_id = fields.Function(inherit_from_parent)

def inherit_from_parent(child, context):
    child['site_id'] = context['site_id']
    return child

【讨论】:

  • 哦,很酷,我不知道你可以这样使用上下文!
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多