python-3.x 在类型示例化时为带注解的类型运行pydantic验证器,而不是在分配给BaseModel字段时

dldeef67  于 2023-10-21  发布在  Python
关注(0)|答案(2)|浏览(136)

我有一个使用fastapi和pydantic的项目。我想定义标准库类型的某些子类型,例如:

def check_negative(v: int) -> int:
    assert v >= 0, f"{v} is negative"
    return v

PositiveInt = Annotated[int, AfterValidator(check_negative)]

class DemoModel(BaseModel):
    numbers: list[PositiveInt]

问题:

以下代码仅在DemoModel示例化时传递数字列表时才运行求值。这意味着numbers在实际用于BaseModel之前包含假值。这是不方便的,因为我想直接在定义的fastapi端点的路由中计算值,而不是等到值被传递到模型。

numbers = [PositiveInt(2), PositiveInt(-3)] <--- should throw evaluation error here
print(numbers)
demo = DemoModel(numbers=numbers) <--- throws evaluation error here

问题:

有没有一种方法可以直接在类型PositiveInt的示例化上运行像AfterValidator这样的验证,而不仅仅是在它用于BaseModel类的示例化时?
因此,在给定的示例中,验证错误将在第一行numbers = [PositiveInt(2), PositiveInt(-3)]中抛出,而不是在最后的demo = DemoModel(numbers=numbers)中抛出。
谢谢你的帮助!

klsxnrf1

klsxnrf11#

不确定这是否是最好的方法,但这是我在阅读pydantic文档的这一部分后如何让它工作的:

class PositiveInt(int):
    def __new__(cls, number: int):
        check_negative(number)
        return super().__new__(cls, number)

    @classmethod
    def __get_pydantic_core_schema__(
        cls, source: Type[Any], handler: GetCoreSchemaHandler
    ) -> core_schema.CoreSchema:
        return core_schema.general_after_validator_function(
            cls.validate,
            core_schema.int_schema(),
            serialization=core_schema.int_schema(),
        )

    @classmethod
    def validate(cls, v: int, _info):
        return check_negative(v)

class DemoModel(BaseModel):
    numbers: list[PositiveInt]

这在PositiveInt的示例化上给了我Assert错误,我也可以在DemoModel中使用它。

if __name__ == "__main__":
    a = PositiveInt(1)
    b = PositiveInt(-3)

    c = DemoModel(numbers=[PositiveInt(1), PositiveInt(-3)])
93ze6v8z

93ze6v8z2#

你可以这样使用TypeAdapter

from pydantic import TypeAdapter

TypeAdapter(list[PositiveInt]).validate_python([2, -3])

关于类型适配器的Python文档:https://docs.pydantic.dev/latest/api/type_adapter/

相关问题