marshmallow嵌套更改架构行为

时间:2015-11-18 14:07:00

标签: python

我想知道如何将上下文传递给嵌套的Schema字段 它的序列化方式与嵌套时不同。

我有一个Schema子类,在@post_dump中添加了一些内容,具体取决于某些flag arg:

class MySchema(Schema):
    def __init__(self, flag=False, *args, **kwargs):
        self.flag = flag
        super(MySchema, self).__init__(*args, **kwargs)

     @post_dump
     def add_thing(self, data):
         if self.flag:
              #add {'NESTED' : 'some_value'} to data
         else:
              #add {'NOT_NESTED' : 'some_value'} to data
         return data

我有一个标准的嵌套模式,大概如下:

class ASchema(MySchema):
  id = fields.Integer()
  b  = fields.Nested(BSchema, flag=True)

class BSchema(MySchema):
  x = fields.Integer()
  y = fields.Integer()

我最终得到的ASchema序列化如下:

{ 'id' : 5,
  'NOT_NESTED' : 'some_value',
  'b'  : { 'x' : 10,
           'y' : 15,
           'NOT_NESTED' : 'some_value',
         }
}

如果我的BSchema是嵌套的,我希望MySchema中的post_dump能够通过flag告诉。

查看fields.Nested()的来源,它会将一些**kwargs传递给Field.__init__(),但在_serialize()方法中,它只会返回Bschema.dump()。< / p>

我是否可以根据是否嵌套来更改字段的序列化?

2 个答案:

答案 0 :(得分:2)

我最终创建了一个field.Nested子类,它将Schema标记为嵌套:

class FlaggedNestedField(fields.Nested):

    @property
    def schema(self):
        schema = super(FlaggedNestedField, self).schema
        setattr(schema, "nested", True)
        return schema

然后我创建了一个我的其他模式扩展的Schema子类,它使用该标志来决定在@post_dump中做什么:

class MySchema(Schema):

    @post_dump(pass_many=True)
    def wrap_with_envelope(self, data, many):
        if getattr(self, "nested", False):
            return data

        return {"data": data}

这是必要的,因为模式之间的依赖关系使我无法使用模式实例。

答案 1 :(得分:1)

您可以使用架构实例配置Nested,而不仅仅是架构类。这样你就可以按自己喜欢的方式配置它:

class ASchema(MySchema):
  id = fields.Integer()
  b  = fields.Nested(BSchema(flag=True))