5

我有一个对象层次结构和一个与之对应的模式层次结构。此层次结构中间级别的模式不包括特定的继承字段。我希望从它继承的模式将“继承”这个排除,但如果他们在他们的 Meta 类中添加自己的排除字段,情况似乎并非如此:

from marshmallow import fields
from marshmallow.schema import Schema


class AncestorSchema(Schema):
    a = fields.Str()
    b = fields.Str()


class IntermediateSchema(AncestorSchema):
    c = fields.Str()

    class Meta:
        exclude = ('b',)


class FinalSchema(IntermediateSchema):
    d = fields.Str()

    class Meta:
        exclude = ('c',)


value = dict(
    a="Field A",
    b="Field B",
    c="Field C",
    d="Field D"
)

print(IntermediateSchema().dump(value).data)

>>> {'c': 'Field C', 'a': 'Field A'}

print(FinalSchema().dump(value).data)

>>> {'d': 'Field D', 'a': 'Field A', 'b': 'Field B'}

在上面的示例中,FinalSchema继承自IntermediateSchema(不包括 field b)并c在其自己的Meta类中排除 field。预期的行为是生成的架构将同时排除band c,但实际上它仅排除c.

当然,可以手动将超模式的排除字段包含在继承模式的排除字段中,但这不是继承的重点,而且很麻烦。

我想知道是否可以以一种优雅的方式实现所需的行为,或者模式继承的当前行为是否实际上是一个错误。

检查 marshmallow 的源代码表明,至少部分支持从超级模式的元类继承数据(即,ordered元选项值是从超级模式继承的)。

4

2 回答 2

4

您还需要指定 Meta 类的基类。您还需要使用某种反射从基类中获取值并附加到它。

from marshmallow import fields
from marshmallow.schema import Schema


class AncestorSchema(Schema):
    a = fields.Str()
    b = fields.Str()


class IntermediateSchema(AncestorSchema):
    c = fields.Str()

    class Meta:
        exclude = ('b',)


class FinalSchema(IntermediateSchema):
    d = fields.Str()

    def __init__(self, *args, **kwargs):
        self.opts.exclude += ('c',)
        super().__init__(*args, **kwargs)
于 2018-03-08T12:39:46.910 回答
4

另一个答案不起作用,因为self没有定义。我找到了一个可行的解决方案。

from marshmallow import fields
from marshmallow.schema import Schema


class AncestorSchema(Schema):
    a = fields.Str()
    b = fields.Str()


class IntermediateSchema(AncestorSchema):
    c = fields.Str()

    class Meta:
        exclude = ('b',)


class FinalSchema(IntermediateSchema):
    d = fields.Str()

    def __init__(self, *args, **kwargs):
        self.opts.exclude += ('c',)
        super().__init__(*args, **kwargs)
于 2019-07-17T10:17:50.820 回答