跳转到内容

函数式验证器

此模块包含用于验证的相关类和函数。

ModelAfterValidatorWithoutInfo module-attribute

ModelAfterValidatorWithoutInfo = Callable[
    [_ModelType], _ModelType
]

一个用 @model_validator 装饰的函数签名。当 mode='after' 且函数没有 info 参数时使用。

ModelAfterValidator module-attribute

ModelAfterValidator = Callable[
    [_ModelType, ValidationInfo[Any]], _ModelType
]

一个用 @model_validator 装饰的函数签名。当 mode='after' 时使用。

AfterValidator dataclass

AfterValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
)

使用文档

字段 after 验证器

一个元数据类,指示验证应该在内部验证逻辑 **之后** 应用。

属性

名称 类型 描述
func NoInfoValidatorFunction | WithInfoValidatorFunction

验证器函数。

示例
from typing import Annotated

from pydantic import AfterValidator, BaseModel, ValidationError

MyInt = Annotated[int, AfterValidator(lambda v: v + 1)]

class Model(BaseModel):
    a: MyInt

print(Model(a=1).a)
#> 2

try:
    Model(a='a')
except ValidationError as e:
    print(e.json(indent=2))
    '''
    [
      {
        "type": "int_parsing",
        "loc": [
          "a"
        ],
        "msg": "Input should be a valid integer, unable to parse string as an integer",
        "input": "a",
        "url": "https://errors.pydantic.dev/2/v/int_parsing"
      }
    ]
    '''

BeforeValidator dataclass

BeforeValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
    json_schema_input_type: Any = PydanticUndefined,
)

一个元数据类,指示验证应该在内部验证逻辑 **之前** 应用。

属性

名称 类型 描述
func NoInfoValidatorFunction | WithInfoValidatorFunction

验证器函数。

json_schema_input_type Any

用于生成适当 JSON Schema (在验证模式下) 的输入类型。实际输入类型为 Any

示例
from typing import Annotated

from pydantic import BaseModel, BeforeValidator

MyInt = Annotated[int, BeforeValidator(lambda v: v + 1)]

class Model(BaseModel):
    a: MyInt

print(Model(a=1).a)
#> 2

try:
    Model(a='a')
except TypeError as e:
    print(e)
    #> can only concatenate str (not "int") to str

PlainValidator dataclass

PlainValidator(
    func: (
        NoInfoValidatorFunction | WithInfoValidatorFunction
    ),
    json_schema_input_type: Any = Any,
)

使用文档

字段 plain 验证器

一个元数据类,指示验证应该 **代替** 内部验证逻辑应用。

注意

在 v2.9 之前,PlainValidator 并不总是与 mode='validation' 的 JSON Schema 生成兼容。现在,您可以使用 json_schema_input_type 参数来指定当 mode='validation'(默认)时,用于 JSON Schema 的函数的输入类型。有关更多详细信息,请参见下面的示例。

属性

名称 类型 描述
func NoInfoValidatorFunction | WithInfoValidatorFunction

验证器函数。

json_schema_input_type Any

用于生成适当 JSON Schema (在验证模式下) 的输入类型。实际输入类型为 Any

示例
from typing import Annotated, Union

from pydantic import BaseModel, PlainValidator

def validate(v: object) -> int:
    if not isinstance(v, (int, str)):
        raise ValueError(f'Expected int or str, go {type(v)}')

    return int(v) + 1

MyInt = Annotated[
    int,
    PlainValidator(validate, json_schema_input_type=Union[str, int]),  # (1)!
]

class Model(BaseModel):
    a: MyInt

print(Model(a='1').a)
#> 2

print(Model(a=1).a)
#> 2
  1. 在此示例中,我们已将 json_schema_input_type 指定为 Union[str, int],这向 JSON schema 生成器指示在验证模式下,字段 a 的输入类型可以是 strint

WrapValidator dataclass

WrapValidator(
    func: (
        NoInfoWrapValidatorFunction
        | WithInfoWrapValidatorFunction
    ),
    json_schema_input_type: Any = PydanticUndefined,
)

使用文档

字段 wrap 验证器

一个元数据类,指示验证应该 **围绕** 内部验证逻辑应用。

属性

名称 类型 描述
func NoInfoWrapValidatorFunction | WithInfoWrapValidatorFunction

验证器函数。

json_schema_input_type Any

用于生成适当 JSON Schema (在验证模式下) 的输入类型。实际输入类型为 Any

from datetime import datetime
from typing import Annotated

from pydantic import BaseModel, ValidationError, WrapValidator

def validate_timestamp(v, handler):
    if v == 'now':
        # we don't want to bother with further validation, just return the new value
        return datetime.now()
    try:
        return handler(v)
    except ValidationError:
        # validation failed, in this case we want to return a default value
        return datetime(2000, 1, 1)

MyTimestamp = Annotated[datetime, WrapValidator(validate_timestamp)]

class Model(BaseModel):
    a: MyTimestamp

print(Model(a='now').a)
#> 2032-01-02 03:04:05.000006
print(Model(a='invalid').a)
#> 2000-01-01 00:00:00

ModelWrapValidatorHandler

基类: ValidatorFunctionWrapHandler, Protocol[_ModelTypeCo]

@model_validator 装饰的函数处理程序参数类型。当 mode='wrap' 时使用。

ModelWrapValidatorWithoutInfo

基类: Protocol[_ModelType]

一个用 @model_validator 装饰的函数签名。当 mode='wrap' 且函数没有 info 参数时使用。

ModelWrapValidator

基类: Protocol[_ModelType]

一个用 @model_validator 装饰的函数签名。当 mode='wrap' 时使用。

FreeModelBeforeValidatorWithoutInfo

基类: Protocol

一个用 @model_validator 装饰的函数签名。当 mode='before' 且函数没有 info 参数时使用。

ModelBeforeValidatorWithoutInfo

基类: Protocol

一个用 @model_validator 装饰的函数签名。当 mode='before' 且函数没有 info 参数时使用。

FreeModelBeforeValidator

基类: Protocol

一个用 @model_validator 装饰的函数签名。当 mode='before' 时使用。

ModelBeforeValidator

基类: Protocol

一个用 @model_validator 装饰的函数签名。当 mode='before' 时使用。

InstanceOf dataclass

InstanceOf()

用于标注给定类的实例的通用类型。

示例
from pydantic import BaseModel, InstanceOf

class Foo:
    ...

class Bar(BaseModel):
    foo: InstanceOf[Foo]

Bar(foo=Foo())
try:
    Bar(foo=42)
except ValidationError as e:
    print(e)
    """
    [
    │   {
    │   │   'type': 'is_instance_of',
    │   │   'loc': ('foo',),
    │   │   'msg': 'Input should be an instance of Foo',
    │   │   'input': 42,
    │   │   'ctx': {'class': 'Foo'},
    │   │   'url': 'https://errors.pydantic.dev/0.38.0/v/is_instance_of'
    │   }
    ]
    """

SkipValidation dataclass

SkipValidation()

如果这被用作注解(例如,通过 x: Annotated[int, SkipValidation]),则将跳过验证。您也可以使用 SkipValidation[int] 作为 Annotated[int, SkipValidation] 的简写。

如果您想将类型注解用于文档/IDE/类型检查目的,并且知道跳过一个或多个字段的验证是安全的,这会很有用。

因为这会将验证模式转换为 any_schema,所以后续应用的注解转换可能不会产生预期的效果。因此,在使用时,此注解通常应是应用于类型的最终注解。

ValidateAs

ValidateAs(
    from_type: type[_FromTypeT],
    /,
    instantiation_hook: Callable[[_FromTypeT], Any],
)

一个辅助类,用于从 Pydantic 原生支持的类型中验证自定义类型。

参数

名称 类型 描述 默认值
from_type type[_FromTypeT]

Pydantic 原生支持的类型,用于执行验证。

必需
instantiation_hook Callable[[_FromTypeT], Any]

一个可调用对象,它以已验证的类型作为参数,并返回已填充的自定义类型。

必需
示例
from typing import Annotated

from pydantic import BaseModel, TypeAdapter, ValidateAs

class MyCls:
    def __init__(self, a: int) -> None:
        self.a = a

    def __repr__(self) -> str:
        return f"MyCls(a={self.a})"

class Model(BaseModel):
    a: int


ta = TypeAdapter(
    Annotated[MyCls, ValidateAs(Model, lambda v: MyCls(a=v.a))]
)

print(ta.validate_python({'a': 1}))
#> MyCls(a=1)
源代码在 pydantic/functional_validators.py
874
875
876
def __init__(self, from_type: type[_FromTypeT], /, instantiation_hook: Callable[[_FromTypeT], Any]) -> None:
    self.from_type = from_type
    self.instantiation_hook = instantiation_hook

field_validator

field_validator(
    field: str,
    /,
    *fields: str,
    mode: Literal["wrap"],
    check_fields: bool | None = ...,
    json_schema_input_type: Any = ...,
) -> Callable[[_V2WrapValidatorType], _V2WrapValidatorType]
field_validator(
    field: str,
    /,
    *fields: str,
    mode: Literal["before", "plain"],
    check_fields: bool | None = ...,
    json_schema_input_type: Any = ...,
) -> Callable[
    [_V2BeforeAfterOrPlainValidatorType],
    _V2BeforeAfterOrPlainValidatorType,
]
field_validator(
    field: str,
    /,
    *fields: str,
    mode: Literal["after"] = ...,
    check_fields: bool | None = ...,
) -> Callable[
    [_V2BeforeAfterOrPlainValidatorType],
    _V2BeforeAfterOrPlainValidatorType,
]
field_validator(
    field: str,
    /,
    *fields: str,
    mode: FieldValidatorModes = "after",
    check_fields: bool | None = None,
    json_schema_input_type: Any = PydanticUndefined,
) -> Callable[[Any], Any]

使用文档

字段验证器

装饰类中的方法,表明它们应该用于验证字段。

用法示例

from typing import Any

from pydantic import (
    BaseModel,
    ValidationError,
    field_validator,
)

class Model(BaseModel):
    a: str

    @field_validator('a')
    @classmethod
    def ensure_foobar(cls, v: Any):
        if 'foobar' not in v:
            raise ValueError('"foobar" not found in a')
        return v

print(repr(Model(a='this is foobar good')))
#> Model(a='this is foobar good')

try:
    Model(a='snap')
except ValidationError as exc_info:
    print(exc_info)
    '''
    1 validation error for Model
    a
      Value error, "foobar" not found in a [type=value_error, input_value='snap', input_type=str]
    '''

有关更深入的示例,请参阅 字段验证器

参数

名称 类型 描述 默认值
field str

field_validator 应该在的第一个字段;这与 fields 分开,以确保如果您不传递至少一个字段,则会引发错误。

必需
*fields str

field_validator 应该在的其他字段。

()
mode FieldValidatorModes

指定是在验证之前还是之后验证字段。

'after'
check_fields bool | None

是否检查模型上实际存在这些字段。

None
json_schema_input_type Any

函数的输入类型。这仅用于生成适当的 JSON Schema(在验证模式下),并且只能在 mode'before''plain''wrap' 时指定。

PydanticUndefined

返回

类型 描述
Callable[[Any], Any]

一个装饰器,可用于装饰函数以用作 field_validator。

抛出

类型 描述
PydanticUserError
  • 如果 @field_validator 直接使用(不带字段)。
  • 如果传递给 @field_validator 作为字段的参数不是字符串。
  • 如果 @field_validator 应用于实例方法。
源代码在 pydantic/functional_validators.py
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
def field_validator(
    field: str,
    /,
    *fields: str,
    mode: FieldValidatorModes = 'after',
    check_fields: bool | None = None,
    json_schema_input_type: Any = PydanticUndefined,
) -> Callable[[Any], Any]:
    """!!! abstract "Usage Documentation"
        [field validators](../concepts/validators.md#field-validators)

    Decorate methods on the class indicating that they should be used to validate fields.

    Example usage:
    ```python
    from typing import Any

    from pydantic import (
        BaseModel,
        ValidationError,
        field_validator,
    )

    class Model(BaseModel):
        a: str

        @field_validator('a')
        @classmethod
        def ensure_foobar(cls, v: Any):
            if 'foobar' not in v:
                raise ValueError('"foobar" not found in a')
            return v

    print(repr(Model(a='this is foobar good')))
    #> Model(a='this is foobar good')

    try:
        Model(a='snap')
    except ValidationError as exc_info:
        print(exc_info)
        '''
        1 validation error for Model
        a
          Value error, "foobar" not found in a [type=value_error, input_value='snap', input_type=str]
        '''
    ```

    For more in depth examples, see [Field Validators](../concepts/validators.md#field-validators).

    Args:
        field: The first field the `field_validator` should be called on; this is separate
            from `fields` to ensure an error is raised if you don't pass at least one.
        *fields: Additional field(s) the `field_validator` should be called on.
        mode: Specifies whether to validate the fields before or after validation.
        check_fields: Whether to check that the fields actually exist on the model.
        json_schema_input_type: The input type of the function. This is only used to generate
            the appropriate JSON Schema (in validation mode) and can only specified
            when `mode` is either `'before'`, `'plain'` or `'wrap'`.

    Returns:
        A decorator that can be used to decorate a function to be used as a field_validator.

    Raises:
        PydanticUserError:
            - If `@field_validator` is used bare (with no fields).
            - If the args passed to `@field_validator` as fields are not strings.
            - If `@field_validator` applied to instance methods.
    """
    if isinstance(field, FunctionType):
        raise PydanticUserError(
            '`@field_validator` should be used with fields and keyword arguments, not bare. '
            "E.g. usage should be `@validator('<field_name>', ...)`",
            code='validator-no-fields',
        )

    if mode not in ('before', 'plain', 'wrap') and json_schema_input_type is not PydanticUndefined:
        raise PydanticUserError(
            f"`json_schema_input_type` can't be used when mode is set to {mode!r}",
            code='validator-input-type',
        )

    if json_schema_input_type is PydanticUndefined and mode == 'plain':
        json_schema_input_type = Any

    fields = field, *fields
    if not all(isinstance(field, str) for field in fields):
        raise PydanticUserError(
            '`@field_validator` fields should be passed as separate string args. '
            "E.g. usage should be `@validator('<field_name_1>', '<field_name_2>', ...)`",
            code='validator-invalid-fields',
        )

    def dec(
        f: Callable[..., Any] | staticmethod[Any, Any] | classmethod[Any, Any, Any],
    ) -> _decorators.PydanticDescriptorProxy[Any]:
        if _decorators.is_instance_method_from_sig(f):
            raise PydanticUserError(
                '`@field_validator` cannot be applied to instance methods', code='validator-instance-method'
            )

        # auto apply the @classmethod decorator
        f = _decorators.ensure_classmethod_based_on_signature(f)

        dec_info = _decorators.FieldValidatorDecoratorInfo(
            fields=fields, mode=mode, check_fields=check_fields, json_schema_input_type=json_schema_input_type
        )
        return _decorators.PydanticDescriptorProxy(f, dec_info)

    return dec

model_validator

model_validator(*, mode: Literal["wrap"]) -> Callable[
    [_AnyModelWrapValidator[_ModelType]],
    PydanticDescriptorProxy[ModelValidatorDecoratorInfo],
]
model_validator(*, mode: Literal["before"]) -> Callable[
    [_AnyModelBeforeValidator],
    PydanticDescriptorProxy[ModelValidatorDecoratorInfo],
]
model_validator(*, mode: Literal["after"]) -> Callable[
    [_AnyModelAfterValidator[_ModelType]],
    PydanticDescriptorProxy[ModelValidatorDecoratorInfo],
]
model_validator(
    *, mode: Literal["wrap", "before", "after"]
) -> Any

使用文档

模型验证器

装饰模型方法以进行验证。

用法示例

from typing_extensions import Self

from pydantic import BaseModel, ValidationError, model_validator

class Square(BaseModel):
    width: float
    height: float

    @model_validator(mode='after')
    def verify_square(self) -> Self:
        if self.width != self.height:
            raise ValueError('width and height do not match')
        return self

s = Square(width=1, height=1)
print(repr(s))
#> Square(width=1.0, height=1.0)

try:
    Square(width=1, height=2)
except ValidationError as e:
    print(e)
    '''
    1 validation error for Square
      Value error, width and height do not match [type=value_error, input_value={'width': 1, 'height': 2}, input_type=dict]
    '''

有关更深入的示例,请参阅 模型验证器

参数

名称 类型 描述 默认值
mode Literal['wrap', 'before', 'after']

一个必需的字符串字面量,指定验证模式。它可以是以下之一:'wrap'、'before' 或 'after'。

必需

返回

类型 描述
Any

一个装饰器,可用于装饰函数以用作模型验证器。

源代码在 pydantic/functional_validators.py
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
def model_validator(
    *,
    mode: Literal['wrap', 'before', 'after'],
) -> Any:
    """!!! abstract "Usage Documentation"
        [Model Validators](../concepts/validators.md#model-validators)

    Decorate model methods for validation purposes.

    Example usage:
    ```python
    from typing_extensions import Self

    from pydantic import BaseModel, ValidationError, model_validator

    class Square(BaseModel):
        width: float
        height: float

        @model_validator(mode='after')
        def verify_square(self) -> Self:
            if self.width != self.height:
                raise ValueError('width and height do not match')
            return self

    s = Square(width=1, height=1)
    print(repr(s))
    #> Square(width=1.0, height=1.0)

    try:
        Square(width=1, height=2)
    except ValidationError as e:
        print(e)
        '''
        1 validation error for Square
          Value error, width and height do not match [type=value_error, input_value={'width': 1, 'height': 2}, input_type=dict]
        '''
    ```

    For more in depth examples, see [Model Validators](../concepts/validators.md#model-validators).

    Args:
        mode: A required string literal that specifies the validation mode.
            It can be one of the following: 'wrap', 'before', or 'after'.

    Returns:
        A decorator that can be used to decorate a function to be used as a model validator.
    """

    def dec(f: Any) -> _decorators.PydanticDescriptorProxy[Any]:
        # auto apply the @classmethod decorator (except for *after* validators, which should be instance methods):
        if mode != 'after':
            f = _decorators.ensure_classmethod_based_on_signature(f)
        dec_info = _decorators.ModelValidatorDecoratorInfo(mode=mode)
        return _decorators.PydanticDescriptorProxy(f, dec_info)

    return dec