Pydantic V2 中的计算字段 - 我可以添加用于验证和序列化的别名吗?

问题描述 投票:0回答:1

背景

在 Pydantic 模型中,我想根据第三个字段包含的值设置两个字段的值。但我还想设置一些微妙的别名。

所以如果我们有:

class FooModel(BaseModel):
    data_holder: list = Field(..., exclude=True)

    # Values of bar and baz below will be set based on values in data_holder
    bar: int = Field(..., validation_alias=AliasChoices(‘bar’, ‘Bar’), serialization_alias=‘Bar’)
    baz: int = Field(..., validation_alias=AliasChoices(‘baz’, ‘Baz’), serialization_alias=‘Baz’)

我也这样做:

foo = FooModel(data_holder=[123, 456])

我想要:

# The model will compute:
    bar=123 # Field validation and serialization rules apply
    baz=456 # Field validation and serialization rules apply

# Such that:

print(bar)
#> Bar='123'
print(baz)
#> Baz='456'

问题

--> 使用

@computed_field
可以做到这一点吗,或者还有其他推荐的方法吗?

计算字段似乎是显而易见的方法,但是基于文档我没有看到添加验证和序列化别名选项的方法。我相信
root_validator
在 V1 中提供了解决方案,但已被弃用。我也考虑过使用“之前”
field_validator
,但还没有让它适用于我的实际用例。 (现实世界的环境更加混乱,
data_holder
实际上是另一个 Pydantic 模型)。

python class validation inheritance pydantic
1个回答
0
投票

这似乎与您要问的非常接近:

class FooModel(BaseModel):
    data_holder: list[int] = Field(exclude=True)

    @computed_field(alias='Bar')
    def bar(self) -> int:
        return self.data_holder[0]

    @computed_field(alias='Baz')
    def baz(self) -> int:
        return self.data_holder[1]

data_holder
用于实例化,
Bar
Baz
用于序列化:

foo = FooModel(data_holder=[123, 456])

print(foo)
# -> FooModel(data_holder=[123, 456], bar=123, baz=456)

foo.model_dump(by_alias=True)
# -> {'Bar': 123, 'Baz': 456}

这是我的理解:

  1. validation_alias
    仅用于实例化/加载,
    serialization_alias
    用于转储,
    alias
    是两者的简写,但如果提供,则其他优先。
  2. FooModel.bar
    FooModel.baz
    是根据
    FooModel.data_holder
    计算的。如果在实例化期间提供,它们将被忽略,因此
    validation_alias
    将毫无意义,并且
    serialization_alias
    隐含于
    alias
    。因此,只有
    alias
    可用于
    @computed_field()
  3. exclude=True
    上的
    data_holder
    确保在转储时始终将其排除,但它在类实例上仍然可用。
  4. 对于
    print()
    ,如果您想隐藏
    data_holder
    或显示
    bar
    baz
    的别名,则需要覆盖
    .__repr__()
    .__repr_args__()
  5. 如果您想默认设置
    .model_dump()
    ,您也可以覆盖
    by_alias=True
© www.soinside.com 2019 - 2024. All rights reserved.