棉花糖序列化嵌套在父字段中
Marshmallow serialize nested with parent field
很抱歉,如果之前有人问过这个问题,我实际上找不到解决方案或类似问题(可能使用了错误的词)。
我正在更新现有的 Flask API,它使用 marshmallow 和 peewee 从我们无法控制的客户端接收数据(无法更改 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,在反序列化以创建时,必须 将其复制到列表中的每个对象中模型并存储数据。
这是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)
这是棉花糖模式:
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() 方法和预加载/post-加载 prodItemSchema 的装饰器从主结构传递站点 ID 的方法,因此模型无法被创建。另外,我希望 marshmallow 为我验证整个结构,而不是像现在在代码中那样在资源和模式之间分两部分进行验证。
但是在文档中找不到制作类似东西的方法,这可能吗?
在 marshmallow 中,可以在序列化之前将值从父方案传递给其子方案,方法是使用 pre_dump decorator on the parent scheme to set the context. Once the context is set, a 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
很抱歉,如果之前有人问过这个问题,我实际上找不到解决方案或类似问题(可能使用了错误的词)。
我正在更新现有的 Flask API,它使用 marshmallow 和 peewee 从我们无法控制的客户端接收数据(无法更改 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,在反序列化以创建时,必须 将其复制到列表中的每个对象中模型并存储数据。
这是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)
这是棉花糖模式:
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() 方法和预加载/post-加载 prodItemSchema 的装饰器从主结构传递站点 ID 的方法,因此模型无法被创建。另外,我希望 marshmallow 为我验证整个结构,而不是像现在在代码中那样在资源和模式之间分两部分进行验证。
但是在文档中找不到制作类似东西的方法,这可能吗?
在 marshmallow 中,可以在序列化之前将值从父方案传递给其子方案,方法是使用 pre_dump decorator on the parent scheme to set the context. Once the context is set, a 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