pydantic中有post_load吗?

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

之前我在 Flask 中使用了 marshmallow 库。前段时间我尝试过 FastAPI 和 Pydantic。乍一看,

pydantic
似乎与
masrhmallow
相似,但仔细观察它们却有所不同。对我来说,它们之间的主要区别是来自 marshmallow
post_load
方法。我在
pydantic
中找不到任何类似物。

post_load
是后处理方法的装饰器。使用它我可以自己处理返回对象,可以做任何我想做的事:

class ProductSchema(Schema):
    alias = fields.Str()
    category = fields.Str()
    brand = fields.Str()

    @post_load
    def check_alias(self, params, **kwargs):
        """One of the fields must be filled"""
        if not any([params.get('alias'), params.get('category'), params.get('brand')]):
            raise ValidationError('No alias provided', field='alias')
        return params

此外它不仅用于验证。代码示例仅供直观理解,请勿分析,我刚刚发明的。

所以我的问题是:

post_load
中是否有
pydantic
的类似物?

python pydantic
3个回答
15
投票

这并不明显,但

pydantic's
验证器返回字段的值。

Pydantic v1

有两种方法处理

post_load
转换:
validator
root_validator
.

validator
获取字段值作为参数并返回其值。
root_validator
相同,但操纵整个对象。

from pydantic import validator, root_validator


class PaymentStatusSchema(BaseModel):
    order_id: str = Param(..., title="Order id in the shop")
    order_number: str = Param(..., title="Order number in chronological order")
    status: int = Param(..., title="Payment status")

    @validator("status")
    def convert_status(cls, status):
        return "active" if status == 1 else "inactive"

    @root_validator
    def validate_order_id(cls, values):
        """Check order id"""
        if not values.get('orderNumber') and not values.get('mdOrder'):
            raise HTTPException(status_code=400, detail='No order data provided')
        return values

默认情况下,

pydantic
将验证器作为后处理方法运行。对于预处理,您应该使用带有
pre
参数的验证器:

    @root_validator(pre=True)
    def validate_order_id(cls, values):
        """Check order id"""
        # some code here
        return values

Pydantic v2

在 Pydantic v2 验证器中迁移:

validator
field_validator
root_validator
model_validator

@field_validator('status')
@classmethod
def convert_status(cls, status: int):
    return "active" if status == 1 else "inactive"

@model_validator(mode='after')
@classmethod
def validate_order_id(cls, values):
    """Check order id"""
    if not values.get('orderNumber') and not values.get('mdOrder'):
        raise HTTPException(status_code=400, detail='No order data provided')
    return values

对于后处理或预处理,请使用

mode
参数。


1
投票

是的,您可以使用 Pydantic 的

@validator
decorator 进行预加载、后加载、模型验证等。

这是一个加载后示例

from pydantic import validator

class Person(BaseModel):
    first_name: str
    second_name: str

    @validator("first_name")
    def make_it_formal(cls, first_name):
        return f"Mr. {first_name.capitalize()}"



p = Person(first_name="egvo", second_name="Example")

p.first_name
Out: Mr. Egvo

1
投票

或者,您也可以覆盖

__init__
并在那里对实例进行后处理:

from pydantic import BaseModel

class ProductSchema(BaseModel):
    alias: str
    category: str
    brand: str

    def __init__(self, *args, **kwargs):

        # Do Pydantic validation
        super().__init__(*args, **kwargs)

        # Do things after Pydantic validation
        if not any([self.alias, self.category, self.brand]):
            raise ValueError("No alias provided")

尽管这种情况发生在 Pydantic 的验证之外。

© www.soinside.com 2019 - 2024. All rights reserved.