pydantic中有post_load吗?

egv*_*gvo 11 python pydantic

之前我将Marshmallow库与 Flask 一起使用。前段时间我尝试过 FastAPI 和Pydantic。乍一看pydantic似乎相似,masrhmallow但仔细观察却有所不同。对我来说,它们之间的主要区别是来自marshmallow. 我在 中找不到任何类似的东西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
Run Code Online (Sandbox Code Playgroud)

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

post_load所以我的问题是: in是否有类似的东西pydantic

egv*_*gvo 15

这并不明显,但pydantic's验证器返回字段的值。

派丹提克 v1

有两种处理post_load转换的方法:validatorroot_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
Run Code Online (Sandbox Code Playgroud)

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

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

派丹提克 v2

在 Pydantic v2 中,验证器迁移:validatorfield_validatorroot_validatormodel_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
Run Code Online (Sandbox Code Playgroud)

对于后处理或预处理使用mode参数。