pydantic里有post_load吗?

Is there any post_load in pydantic?

之前我使用了来自marshmallowmarshmallow library with the Flask. Some time ago I have tried FastAPI with Pydantic. At first glance pydantic seems similar to masrhmallow but on closer inspection they differ. And for me the main difference between them is post_load方法。我在 pydantic.

中找不到任何类似物

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

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

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

所以我的问题是: pydantic 中是否有 post_load 的模拟?

是的,您可以使用 Pydantic @validator decorator 进行 pre-load、post-load、模型验证等

这是一个Post加载示例

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

不明显,但 pydantic's 验证器 returns 字段的值。所以有两种方法可以处理 post_load 转换:validatorroot_validator.

validator 获取字段值作为参数,returns 它的值。 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 check_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 将验证程序作为 post-processing 方法运行。对于 pre-processing 你应该使用带有 pre 参数的验证器:

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