跳到内容

配置

Pydantic 模型的配置。

ConfigDict

基类: TypedDict

用于配置 Pydantic 行为的 TypedDict。

title instance-attribute

title: str | None

为生成的 JSON schema 设置标题,默认为模型的名称

model_title_generator instance-attribute

model_title_generator: Callable[[type], str] | None

一个可调用对象,接受一个模型类并返回其标题。默认为 None

field_title_generator instance-attribute

field_title_generator: (
    Callable[[str, FieldInfo | ComputedFieldInfo], str]
    | None
)

一个可调用对象,接受一个字段的名称和信息,并为其返回标题。默认为 None

str_to_lower instance-attribute

str_to_lower: bool

是否将 str 类型的所有字符转换为小写。默认为 False

str_to_upper instance-attribute

str_to_upper: bool

是否将 str 类型的所有字符转换为大写。默认为 False

str_strip_whitespace instance-attribute

str_strip_whitespace: bool

是否去除 str 类型的前导和尾随空格。

str_min_length instance-attribute

str_min_length: int

str 类型的最小长度。默认为 None

str_max_length instance-attribute

str_max_length: int | None

str 类型的最大长度。默认为 None

extra instance-attribute

extra: ExtraValues | None

在模型初始化期间,是否忽略、允许或禁止额外数据。默认为 'ignore'

有三个可用的配置值

  • 'ignore':提供额外数据将被忽略(默认)

    from pydantic import BaseModel, ConfigDict
    
    class User(BaseModel):
        model_config = ConfigDict(extra='ignore')  # (1)!
    
        name: str
    
    user = User(name='John Doe', age=20)  # (2)!
    print(user)
    #> name='John Doe'
    

    1. 这是默认行为。
    2. age 参数将被忽略。
  • 'forbid':不允许提供额外数据,如果出现这种情况,将引发 ValidationError

    from pydantic import BaseModel, ConfigDict, ValidationError
    
    
    class Model(BaseModel):
        x: int
    
        model_config = ConfigDict(extra='forbid')
    
    
    try:
        Model(x=1, y='a')
    except ValidationError as exc:
        print(exc)
        """
        1 validation error for Model
        y
          Extra inputs are not permitted [type=extra_forbidden, input_value='a', input_type=str]
        """
    

  • 'allow':允许提供额外数据,并将其存储在 __pydantic_extra__ 字典属性中

    from pydantic import BaseModel, ConfigDict
    
    
    class Model(BaseModel):
        x: int
    
        model_config = ConfigDict(extra='allow')
    
    
    m = Model(x=1, y='a')
    assert m.__pydantic_extra__ == {'y': 'a'}
    
    默认情况下,不会对这些额外项目应用验证,但是您可以通过覆盖 __pydantic_extra__ 的类型注解来为这些值设置类型
    from pydantic import BaseModel, ConfigDict, Field, ValidationError
    
    
    class Model(BaseModel):
        __pydantic_extra__: dict[str, int] = Field(init=False)  # (1)!
    
        x: int
    
        model_config = ConfigDict(extra='allow')
    
    
    try:
        Model(x=1, y='a')
    except ValidationError as exc:
        print(exc)
        """
        1 validation error for Model
        y
          Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='a', input_type=str]
        """
    
    m = Model(x=1, y='2')
    assert m.x == 1
    assert m.y == 2
    assert m.model_dump() == {'x': 1, 'y': 2}
    assert m.__pydantic_extra__ == {'y': 2}
    

    1. = Field(init=False) 在运行时没有任何效果,但可以防止类型检查器将 __pydantic_extra__ 字段包含为模型 __init__ 方法的参数。

frozen instance-attribute

frozen: bool

模型是否为伪不可变,即是否允许 __setattr__,以及是否为模型生成 __hash__() 方法。如果所有属性都是可哈希的,这将使模型的实例可能可哈希。默认为 False

注意

在 V1 版本中,此设置的相反值称为 allow_mutation,默认值为 True

populate_by_name instance-attribute

populate_by_name: bool

是否可以通过模型的属性名称以及别名来填充别名字段。默认为 False

警告

不建议在 v2.11+ 中使用 populate_by_name,并且将在 v3 中弃用。相反,您应该使用 validate_by_name 配置设置。

validate_by_name=Truevalidate_by_alias=True 时,这与之前 populate_by_name=True 的行为严格等效。

在 v2.11 中,我们还引入了 validate_by_alias 设置,该设置为验证行为引入了更细粒度的控制。

以下是如何使用新设置来实现相同行为的方法

from pydantic import BaseModel, ConfigDict, Field

class Model(BaseModel):
    model_config = ConfigDict(validate_by_name=True, validate_by_alias=True)

    my_field: str = Field(alias='my_alias')  # (1)!

m = Model(my_alias='foo')  # (2)!
print(m)
#> my_field='foo'

m = Model(my_alias='foo')  # (3)!
print(m)
#> my_field='foo'
  1. 字段 'my_field' 有一个别名 'my_alias'
  2. 模型由别名 'my_alias' 填充。
  3. 模型由属性名称 'my_field' 填充。

use_enum_values instance-attribute

use_enum_values: bool

是否使用枚举的 value 属性而不是原始枚举来填充模型。如果您希望稍后序列化 model.model_dump(),这可能很有用。默认为 False

注意

如果您有一个 Optional[Enum] 值,您为其设置了默认值,则需要使用 validate_default=True 来确保 use_enum_values 标志对默认值生效,因为提取枚举的值发生在验证期间,而不是序列化期间。

from enum import Enum
from typing import Optional

from pydantic import BaseModel, ConfigDict, Field

class SomeEnum(Enum):
    FOO = 'foo'
    BAR = 'bar'
    BAZ = 'baz'

class SomeModel(BaseModel):
    model_config = ConfigDict(use_enum_values=True)

    some_enum: SomeEnum
    another_enum: Optional[SomeEnum] = Field(
        default=SomeEnum.FOO, validate_default=True
    )

model1 = SomeModel(some_enum=SomeEnum.BAR)
print(model1.model_dump())
#> {'some_enum': 'bar', 'another_enum': 'foo'}

model2 = SomeModel(some_enum=SomeEnum.BAR, another_enum=SomeEnum.BAZ)
print(model2.model_dump())
#> {'some_enum': 'bar', 'another_enum': 'baz'}

validate_assignment instance-attribute

validate_assignment: bool

模型更改时是否验证数据。默认为 False

Pydantic 的默认行为是在创建模型时验证数据。

如果用户在创建模型后更改数据,则模型不会重新验证。

from pydantic import BaseModel

class User(BaseModel):
    name: str

user = User(name='John Doe')  # (1)!
print(user)
#> name='John Doe'
user.name = 123  # (1)!
print(user)
#> name=123
  1. 验证仅在创建模型时发生。
  2. 当数据更改时,验证不会发生。

如果您希望在数据更改时重新验证模型,可以使用 validate_assignment=True

from pydantic import BaseModel, ValidationError

class User(BaseModel, validate_assignment=True):  # (1)!
    name: str

user = User(name='John Doe')  # (2)!
print(user)
#> name='John Doe'
try:
    user.name = 123  # (3)!
except ValidationError as e:
    print(e)
    '''
    1 validation error for User
    name
      Input should be a valid string [type=string_type, input_value=123, input_type=int]
    '''
  1. 您可以使用类关键字参数或 model_config 来设置 validate_assignment=True
  2. 验证在创建模型时发生。
  3. 验证在数据更改时发生。

arbitrary_types_allowed instance-attribute

arbitrary_types_allowed: bool

是否允许字段类型使用任意类型。默认为 False

from pydantic import BaseModel, ConfigDict, ValidationError

# This is not a pydantic model, it's an arbitrary class
class Pet:
    def __init__(self, name: str):
        self.name = name

class Model(BaseModel):
    model_config = ConfigDict(arbitrary_types_allowed=True)

    pet: Pet
    owner: str

pet = Pet(name='Hedwig')
# A simple check of instance type is used to validate the data
model = Model(owner='Harry', pet=pet)
print(model)
#> pet=<__main__.Pet object at 0x0123456789ab> owner='Harry'
print(model.pet)
#> <__main__.Pet object at 0x0123456789ab>
print(model.pet.name)
#> Hedwig
print(type(model.pet))
#> <class '__main__.Pet'>
try:
    # If the value is not an instance of the type, it's invalid
    Model(owner='Harry', pet='Hedwig')
except ValidationError as e:
    print(e)
    '''
    1 validation error for Model
    pet
      Input should be an instance of Pet [type=is_instance_of, input_value='Hedwig', input_type=str]
    '''

# Nothing in the instance of the arbitrary type is checked
# Here name probably should have been a str, but it's not validated
pet2 = Pet(name=42)
model2 = Model(owner='Harry', pet=pet2)
print(model2)
#> pet=<__main__.Pet object at 0x0123456789ab> owner='Harry'
print(model2.pet)
#> <__main__.Pet object at 0x0123456789ab>
print(model2.pet.name)
#> 42
print(type(model2.pet))
#> <class '__main__.Pet'>

from_attributes instance-attribute

from_attributes: bool

是否使用 Python 对象属性构建模型并查找标记联合的鉴别器。

loc_by_alias instance-attribute

loc_by_alias: bool

对于错误 loc,是否使用数据中提供的实际键(例如别名)而不是字段的名称。默认为 True

alias_generator instance-attribute

alias_generator: (
    Callable[[str], str] | AliasGenerator | None
)

一个可调用对象,接受一个字段名称并为其返回别名或 AliasGenerator 的实例。默认为 None

当使用可调用对象时,别名生成器用于验证和序列化。如果您想为验证和序列化使用不同的别名生成器,可以使用 AliasGenerator

如果数据源字段名称与您的代码风格不匹配(例如 CamelCase 字段),您可以使用 alias_generator 自动生成别名。这是一个使用基本可调用对象的示例

from pydantic import BaseModel, ConfigDict
from pydantic.alias_generators import to_pascal

class Voice(BaseModel):
    model_config = ConfigDict(alias_generator=to_pascal)

    name: str
    language_code: str

voice = Voice(Name='Filiz', LanguageCode='tr-TR')
print(voice.language_code)
#> tr-TR
print(voice.model_dump(by_alias=True))
#> {'Name': 'Filiz', 'LanguageCode': 'tr-TR'}

如果您想为验证和序列化使用不同的别名生成器,可以使用 AliasGenerator

from pydantic import AliasGenerator, BaseModel, ConfigDict
from pydantic.alias_generators import to_camel, to_pascal

class Athlete(BaseModel):
    first_name: str
    last_name: str
    sport: str

    model_config = ConfigDict(
        alias_generator=AliasGenerator(
            validation_alias=to_camel,
            serialization_alias=to_pascal,
        )
    )

athlete = Athlete(firstName='John', lastName='Doe', sport='track')
print(athlete.model_dump(by_alias=True))
#> {'FirstName': 'John', 'LastName': 'Doe', 'Sport': 'track'}
注意

Pydantic 提供了三个内置的别名生成器:to_pascalto_camelto_snake

ignored_types instance-attribute

ignored_types: tuple[type, ...]

一个类型元组,这些类型可能作为类属性的值出现,而无需注解。这通常用于自定义描述符(行为类似于 property 的类)。如果在一个没有注解的类上设置了一个属性,并且该属性的类型不在该元组中(或未被 pydantic 识别),则会引发错误。默认为 ()

allow_inf_nan instance-attribute

allow_inf_nan: bool

是否允许无穷大 (+inf-inf) 和 NaN 值用于 float 和 decimal 字段。默认为 True

json_schema_extra instance-attribute

json_schema_extra: JsonDict | JsonSchemaExtraCallable | None

一个 dict 或可调用对象,用于提供额外的 JSON schema 属性。默认为 None

json_encoders instance-attribute

json_encoders: dict[type[object], JsonEncoder] | None

一个用于特定类型的自定义 JSON 编码器的 dict。默认为 None

已弃用

此配置选项是从 v1 版本继承下来的。我们最初计划在 v2 版本中删除它,但没有 1:1 的替代品,所以我们暂时保留它。它仍然已弃用,并且将来可能会被删除。

strict instance-attribute

strict: bool

(V2 版本新增) 如果为 True,则对模型上的所有字段应用严格验证。

默认情况下,Pydantic 会尝试在可能的情况下将值强制转换为正确的类型。

在某些情况下,您可能希望禁用此行为,而是在值的类型与字段的类型注解不匹配时引发错误。

要为模型上的所有字段配置严格模式,可以在模型上设置 strict=True

from pydantic import BaseModel, ConfigDict

class Model(BaseModel):
    model_config = ConfigDict(strict=True)

    name: str
    age: int

有关更多详细信息,请参阅 严格模式

有关 Pydantic 如何在严格和宽松模式下转换数据的更多详细信息,请参阅 转换表

revalidate_instances instance-attribute

revalidate_instances: Literal[
    "always", "never", "subclass-instances"
]

在验证期间何时以及如何重新验证模型和数据类。接受字符串值 'never''always''subclass-instances'。默认为 'never'

  • 'never' 将不会在验证期间重新验证模型和数据类
  • 'always' 将始终在验证期间重新验证模型和数据类
  • 'subclass-instances' 如果实例是模型或数据类的子类,将在验证期间重新验证模型和数据类

默认情况下,模型和数据类实例在验证期间不会重新验证。

from pydantic import BaseModel

class User(BaseModel, revalidate_instances='never'):  # (1)!
    hobbies: list[str]

class SubUser(User):
    sins: list[str]

class Transaction(BaseModel):
    user: User

my_user = User(hobbies=['reading'])
t = Transaction(user=my_user)
print(t)
#> user=User(hobbies=['reading'])

my_user.hobbies = [1]  # (2)!
t = Transaction(user=my_user)  # (3)!
print(t)
#> user=User(hobbies=[1])

my_sub_user = SubUser(hobbies=['scuba diving'], sins=['lying'])
t = Transaction(user=my_sub_user)
print(t)
#> user=SubUser(hobbies=['scuba diving'], sins=['lying'])
  1. revalidate_instances 默认设置为 'never'
  2. 除非您在模型的配置中将 validate_assignment 设置为 True,否则不会验证赋值。
  3. 由于 revalidate_instances 设置为 never,因此不会重新验证。

如果您想在验证期间重新验证实例,可以在模型的配置中将 revalidate_instances 设置为 'always'

from pydantic import BaseModel, ValidationError

class User(BaseModel, revalidate_instances='always'):  # (1)!
    hobbies: list[str]

class SubUser(User):
    sins: list[str]

class Transaction(BaseModel):
    user: User

my_user = User(hobbies=['reading'])
t = Transaction(user=my_user)
print(t)
#> user=User(hobbies=['reading'])

my_user.hobbies = [1]
try:
    t = Transaction(user=my_user)  # (2)!
except ValidationError as e:
    print(e)
    '''
    1 validation error for Transaction
    user.hobbies.0
      Input should be a valid string [type=string_type, input_value=1, input_type=int]
    '''

my_sub_user = SubUser(hobbies=['scuba diving'], sins=['lying'])
t = Transaction(user=my_sub_user)
print(t)  # (3)!
#> user=User(hobbies=['scuba diving'])
  1. revalidate_instances 设置为 'always'
  2. 模型已重新验证,因为 revalidate_instances 设置为 'always'
  3. 使用 'never' 我们会得到 user=SubUser(hobbies=['scuba diving'], sins=['lying'])

也可以将 revalidate_instances 设置为 'subclass-instances',以仅重新验证模型子类的实例。

from pydantic import BaseModel

class User(BaseModel, revalidate_instances='subclass-instances'):  # (1)!
    hobbies: list[str]

class SubUser(User):
    sins: list[str]

class Transaction(BaseModel):
    user: User

my_user = User(hobbies=['reading'])
t = Transaction(user=my_user)
print(t)
#> user=User(hobbies=['reading'])

my_user.hobbies = [1]
t = Transaction(user=my_user)  # (2)!
print(t)
#> user=User(hobbies=[1])

my_sub_user = SubUser(hobbies=['scuba diving'], sins=['lying'])
t = Transaction(user=my_sub_user)
print(t)  # (3)!
#> user=User(hobbies=['scuba diving'])
  1. revalidate_instances 设置为 'subclass-instances'
  2. 这不会重新验证,因为 my_user 不是 User 的子类。
  3. 使用 'never' 我们会得到 user=SubUser(hobbies=['scuba diving'], sins=['lying'])

ser_json_timedelta instance-attribute

ser_json_timedelta: Literal['iso8601', 'float']

JSON 序列化 timedeltas 的格式。接受字符串值 'iso8601''float'。默认为 'iso8601'

  • 'iso8601' 会将 timedeltas 序列化为 ISO 8601 持续时间。
  • 'float' 会将 timedeltas 序列化为总秒数。

ser_json_bytes instance-attribute

ser_json_bytes: Literal['utf8', 'base64', 'hex']

JSON 序列化字节的编码。默认为 'utf8'。设置为等于 val_json_bytes 以在序列化往返后获得相等的值。

  • 'utf8' 会将字节序列化为 UTF-8 字符串。
  • 'base64' 会将字节序列化为 URL 安全的 base64 字符串。
  • 'hex' 会将字节序列化为十六进制字符串。

val_json_bytes instance-attribute

val_json_bytes: Literal['utf8', 'base64', 'hex']

JSON 序列化字节的解码编码。默认为 'utf8'。设置为等于 ser_json_bytes 以在序列化往返后获得相等的值。

  • 'utf8' 会将 UTF-8 字符串反序列化为字节。
  • 'base64' 会将 URL 安全的 base64 字符串反序列化为字节。
  • 'hex' 会将十六进制字符串反序列化为字节。

ser_json_inf_nan instance-attribute

ser_json_inf_nan: Literal['null', 'constants', 'strings']

JSON 序列化无穷大和 NaN 浮点值的编码。默认为 'null'

  • 'null' 会将无穷大和 NaN 值序列化为 null
  • 'constants' 会将无穷大和 NaN 值序列化为 InfinityNaN
  • 'strings' 会将无穷大序列化为字符串 "Infinity",将 NaN 序列化为字符串 "NaN"

validate_default instance-attribute

validate_default: bool

是否在验证期间验证默认值。默认为 False

validate_return instance-attribute

validate_return: bool

是否验证来自调用验证器的返回值。默认为 False

protected_namespaces instance-attribute

protected_namespaces: tuple[str | Pattern[str], ...]

一个 tuple 类型的字符串和/或模式,用于防止模型拥有与其冲突的名称的字段。对于字符串,我们基于前缀进行匹配。例如,如果 'dog' 在受保护的命名空间中,则 'dog_name' 将受到保护。对于模式,我们匹配整个字段名称。例如,如果 re.compile(r'^dog$') 在受保护的命名空间中,则 'dog' 将受到保护,但 'dog_name' 将不会受到保护。默认为 ('model_validate', 'model_dump',)

我们选择这些的原因是为了防止将来与其他验证/转储格式发生冲突 - 例如,model_validate_{some_newly_supported_format}

在 v2.10 之前,Pydantic 使用 ('model_',) 作为此设置的默认值,以防止模型属性和 BaseModel 自身的方法之间发生冲突。鉴于反馈表明此限制在 AI 和数据科学环境中具有局限性(在这些环境中,拥有诸如 model_idmodel_inputmodel_output 等名称的字段很常见),因此在 v2.10 中更改了此设置。

有关更多详细信息,请参阅 https://github.com/pydantic/pydantic/issues/10315。

import warnings

from pydantic import BaseModel

warnings.filterwarnings('error')  # Raise warnings as errors

try:

    class Model(BaseModel):
        model_dump_something: str

except UserWarning as e:
    print(e)
    '''
    Field "model_dump_something" in Model has conflict with protected namespace "model_dump".

    You may be able to resolve this warning by setting `model_config['protected_namespaces'] = ('model_validate',)`.
    '''

您可以使用 protected_namespaces 设置自定义此行为

import re
import warnings

from pydantic import BaseModel, ConfigDict

with warnings.catch_warnings(record=True) as caught_warnings:
    warnings.simplefilter('always')  # Catch all warnings

    class Model(BaseModel):
        safe_field: str
        also_protect_field: str
        protect_this: str

        model_config = ConfigDict(
            protected_namespaces=(
                'protect_me_',
                'also_protect_',
                re.compile('^protect_this$'),
            )
        )

for warning in caught_warnings:
    print(f'{warning.message}')
    '''
    Field "also_protect_field" in Model has conflict with protected namespace "also_protect_".
    You may be able to resolve this warning by setting `model_config['protected_namespaces'] = ('protect_me_', re.compile('^protect_this$'))`.

    Field "protect_this" in Model has conflict with protected namespace "re.compile('^protect_this$')".
    You may be able to resolve this warning by setting `model_config['protected_namespaces'] = ('protect_me_', 'also_protect_')`.
    '''

虽然当项目位于受保护的命名空间中但实际上没有冲突时,Pydantic 只会发出警告,但如果与现有属性发生实际冲突,则会引发错误

from pydantic import BaseModel, ConfigDict

try:

    class Model(BaseModel):
        model_validate: str

        model_config = ConfigDict(protected_namespaces=('model_',))

except NameError as e:
    print(e)
    '''
    Field "model_validate" conflicts with member <bound method BaseModel.model_validate of <class 'pydantic.main.BaseModel'>> of protected namespace "model_".
    '''

hide_input_in_errors instance-attribute

hide_input_in_errors: bool

打印错误时是否隐藏输入。默认为 False

当 Pydantic 在验证期间引发 ValidationError 时,它会显示输入值和类型。

from pydantic import BaseModel, ValidationError

class Model(BaseModel):
    a: str

try:
    Model(a=123)
except ValidationError as e:
    print(e)
    '''
    1 validation error for Model
    a
      Input should be a valid string [type=string_type, input_value=123, input_type=int]
    '''

您可以通过将 hide_input_in_errors 配置设置为 True 来隐藏输入值和类型。

from pydantic import BaseModel, ConfigDict, ValidationError

class Model(BaseModel):
    a: str
    model_config = ConfigDict(hide_input_in_errors=True)

try:
    Model(a=123)
except ValidationError as e:
    print(e)
    '''
    1 validation error for Model
    a
      Input should be a valid string [type=string_type]
    '''

defer_build instance-attribute

defer_build: bool

是否延迟模型验证器和序列化器的构建,直到首次模型验证。默认为 False。

这对于避免构建仅在其他模型中嵌套使用的模型,或者当您想通过 Model.model_rebuild(_types_namespace=...) 手动定义类型命名空间时非常有用。

自 v2.10 起,此设置也适用于 pydantic 数据类和 TypeAdapter 实例。

plugin_settings instance-attribute

plugin_settings: dict[str, object] | None

插件的设置 dict。默认为 None

schema_generator instance-attribute

schema_generator: type[GenerateSchema] | None

警告

schema_generator 在 v2.10 中已弃用。

在 v2.10 之前,此设置被宣传为极易更改。一旦内部核心 schema 生成 API 更加稳定,此接口可能会再次公开,但这可能会在进行重大性能改进之后。

json_schema_serialization_defaults_required instance-attribute

json_schema_serialization_defaults_required: bool

具有默认值的字段是否应在序列化 schema 中标记为必需。默认为 False

这确保了序列化 schema 将反映出具有默认值的字段在序列化模型时将始终存在的事实,即使它不是验证所必需的。

但是,在某些情况下,这可能是不希望的 — 特别是,如果您想在验证和序列化之间共享 schema,并且不介意在序列化期间将具有默认值的字段标记为非必需。有关更多详细信息,请参阅 #7209

from pydantic import BaseModel, ConfigDict

class Model(BaseModel):
    a: str = 'a'

    model_config = ConfigDict(json_schema_serialization_defaults_required=True)

print(Model.model_json_schema(mode='validation'))
'''
{
    'properties': {'a': {'default': 'a', 'title': 'A', 'type': 'string'}},
    'title': 'Model',
    'type': 'object',
}
'''
print(Model.model_json_schema(mode='serialization'))
'''
{
    'properties': {'a': {'default': 'a', 'title': 'A', 'type': 'string'}},
    'required': ['a'],
    'title': 'Model',
    'type': 'object',
}
'''

json_schema_mode_override instance-attribute

json_schema_mode_override: Literal[
    "validation", "serialization", None
]

如果不是 None,则无论传递给函数调用的 mode 是什么,都将使用指定的模式来生成 JSON schema。默认为 None

这提供了一种强制 JSON schema 生成反映特定模式的方法,例如,始终使用验证 schema。

当使用框架(例如 FastAPI)时,这可能很有用,这些框架可能会为验证和序列化生成不同的 schema,而这些 schema 都必须从同一 schema 中引用;当发生这种情况时,我们会自动将 -Input 附加到验证 schema 的定义引用,并将 -Output 附加到序列化 schema 的定义引用。但是,通过指定 json_schema_mode_override,可以防止验证 schema 和序列化 schema 之间的冲突(因为两者都将使用指定的 schema),从而防止将后缀添加到定义引用中。

from pydantic import BaseModel, ConfigDict, Json

class Model(BaseModel):
    a: Json[int]  # requires a string to validate, but will dump an int

print(Model.model_json_schema(mode='serialization'))
'''
{
    'properties': {'a': {'title': 'A', 'type': 'integer'}},
    'required': ['a'],
    'title': 'Model',
    'type': 'object',
}
'''

class ForceInputModel(Model):
    # the following ensures that even with mode='serialization', we
    # will get the schema that would be generated for validation.
    model_config = ConfigDict(json_schema_mode_override='validation')

print(ForceInputModel.model_json_schema(mode='serialization'))
'''
{
    'properties': {
        'a': {
            'contentMediaType': 'application/json',
            'contentSchema': {'type': 'integer'},
            'title': 'A',
            'type': 'string',
        }
    },
    'required': ['a'],
    'title': 'ForceInputModel',
    'type': 'object',
}
'''

coerce_numbers_to_str instance-attribute

coerce_numbers_to_str: bool

如果为 True,则在“宽松”(非严格)模式下启用将任何 Number 类型自动强制转换为 str。默认为 False

默认情况下,Pydantic 不允许将数字类型(intfloatDecimal)强制转换为 str 类型。

from decimal import Decimal

from pydantic import BaseModel, ConfigDict, ValidationError

class Model(BaseModel):
    value: str

try:
    print(Model(value=42))
except ValidationError as e:
    print(e)
    '''
    1 validation error for Model
    value
      Input should be a valid string [type=string_type, input_value=42, input_type=int]
    '''

class Model(BaseModel):
    model_config = ConfigDict(coerce_numbers_to_str=True)

    value: str

repr(Model(value=42).value)
#> "42"
repr(Model(value=42.13).value)
#> "42.13"
repr(Model(value=Decimal('42.13')).value)
#> "42.13"

regex_engine instance-attribute

regex_engine: Literal['rust-regex', 'python-re']

用于模式验证的正则表达式引擎。默认为 'rust-regex'

  • rust-regex 使用 regex Rust crate,它是非回溯的,因此更具 DDoS 抵抗力,但不支持所有正则表达式功能。
  • python-re 使用 re 模块,它支持所有正则表达式功能,但可能速度较慢。

注意

如果您使用编译后的正则表达式模式,则无论此设置如何,都将使用 python-re 引擎。这是为了使诸如 re.IGNORECASE 之类的标志得到尊重。

from pydantic import BaseModel, ConfigDict, Field, ValidationError

class Model(BaseModel):
    model_config = ConfigDict(regex_engine='python-re')

    value: str = Field(pattern=r'^abc(?=def)')

print(Model(value='abcdef').value)
#> abcdef

try:
    print(Model(value='abxyzcdef'))
except ValidationError as e:
    print(e)
    '''
    1 validation error for Model
    value
      String should match pattern '^abc(?=def)' [type=string_pattern_mismatch, input_value='abxyzcdef', input_type=str]
    '''

validation_error_cause instance-attribute

validation_error_cause: bool

如果为 True,则作为验证失败一部分的 Python 异常将显示为异常组作为原因。可能对调试很有用。默认为 False

注意

Python 3.10 及更早版本不支持原生异常组。 <=3.10,必须安装 backport:pip install exceptiongroup

注意

验证错误的结构可能会在未来的 Pydantic 版本中发生更改。Pydantic 不保证其结构。应仅用于可视化回溯调试。

use_attribute_docstrings instance-attribute

use_attribute_docstrings: bool

是否应将属性的文档字符串(紧跟在属性声明之后的裸字符串文字)用于字段描述。默认为 False

在 Pydantic v2.7+ 中可用。

from pydantic import BaseModel, ConfigDict, Field


class Model(BaseModel):
    model_config = ConfigDict(use_attribute_docstrings=True)

    x: str
    """
    Example of an attribute docstring
    """

    y: int = Field(description="Description in Field")
    """
    Description in Field overrides attribute docstring
    """


print(Model.model_fields["x"].description)
# > Example of an attribute docstring
print(Model.model_fields["y"].description)
# > Description in Field
这需要类的源代码在运行时可用。

TypedDict 和 stdlib 数据类一起使用

由于当前的限制,当使用 TypedDict 和 stdlib 数据类时,属性文档字符串检测可能无法按预期工作,尤其是在

  • 使用继承时。
  • 多个类在同一源文件中具有相同的名称时。

cache_strings instance-attribute

cache_strings: bool | Literal['all', 'keys', 'none']

是否缓存字符串以避免构造新的 Python 对象。默认为 True。

启用此设置应显着提高验证性能,同时略微增加内存使用量。

  • True'all'(默认值):缓存所有字符串
  • 'keys':仅缓存字典键
  • False'none':不缓存

注意

True'all' 是在常规验证期间缓存字符串所必需的,因为验证器不知道它们是在键中还是在值中。

提示

如果重复字符串很少见,建议使用 'keys''none' 以减少内存使用,因为如果重复字符串很少见,性能差异可以忽略不计。

validate_by_alias instance-attribute

validate_by_alias: bool

是否允许通过别名填充别名字段。默认为 True

注意

在 v2.11 版本中,引入了 validate_by_alias 并结合 validate_by_name,以便为用户提供更精细的验证控制。在 <v2.11 版本中,禁用通过别名验证是不可能的。

以下是禁用通过别名验证的示例

from pydantic import BaseModel, ConfigDict, Field

class Model(BaseModel):
    model_config = ConfigDict(validate_by_name=True, validate_by_alias=False)

    my_field: str = Field(validation_alias='my_alias')  # (1)!

m = Model(my_field='foo')  # (2)!
print(m)
#> my_field='foo'
  1. 字段 'my_field' 有一个别名 'my_alias'
  2. 该模型只能通过属性名称 'my_field' 填充。

警告

您不能同时将 validate_by_aliasvalidate_by_name 设置为 False。这将使得无法填充属性。

请参阅 usage errors 以获取示例。

如果您将 validate_by_alias 设置为 False,在底层,Pydantic 会动态地将 validate_by_name 设置为 True,以确保验证仍然可以发生。

validate_by_name instance-attribute

validate_by_name: bool

是否允许通过模型属性给出的名称填充别名字段。默认为 False

注意

在 v2.0-v2.10 版本中,populate_by_name 配置设置用于指定是否可以通过名称**和**别名填充字段。

在 v2.11 版本中,引入了 validate_by_name 并结合 validate_by_alias,以便为用户提供更精细的验证行为控制。

from pydantic import BaseModel, ConfigDict, Field

class Model(BaseModel):
    model_config = ConfigDict(validate_by_name=True, validate_by_alias=True)

    my_field: str = Field(validation_alias='my_alias')  # (1)!

m = Model(my_alias='foo')  # (2)!
print(m)
#> my_field='foo'

m = Model(my_field='foo')  # (3)!
print(m)
#> my_field='foo'
  1. 字段 'my_field' 有一个别名 'my_alias'
  2. 模型由别名 'my_alias' 填充。
  3. 模型由属性名称 'my_field' 填充。

警告

您不能同时将 validate_by_aliasvalidate_by_name 设置为 False。这将使得无法填充属性。

请参阅 usage errors 以获取示例。

serialize_by_alias instance-attribute

serialize_by_alias: bool

是否应该通过别名序列化别名字段。默认为 False

注意:在 v2.11 版本中,引入了 serialize_by_alias 以解决 热门请求,从而实现验证和序列化设置的别名行为一致性。在 v3 版本中,默认值预计将更改为 True,以与验证默认值保持一致。

from pydantic import BaseModel, ConfigDict, Field

class Model(BaseModel):
    model_config = ConfigDict(serialize_by_alias=True)

    my_field: str = Field(serialization_alias='my_alias')  # (1)!

m = Model(my_field='foo')
print(m.model_dump())  # (2)!
#> {'my_alias': 'foo'}
  1. 字段 'my_field' 有一个别名 'my_alias'
  2. 该模型使用别名 'my_alias' 序列化 'my_field' 属性。

with_config

with_config(
    *, config: ConfigDict
) -> Callable[[_TypeT], _TypeT]
with_config(
    config: ConfigDict,
) -> Callable[[_TypeT], _TypeT]
with_config(
    **config: Unpack[ConfigDict],
) -> Callable[[_TypeT], _TypeT]
with_config(
    config: ConfigDict | None = None, /, **kwargs: Any
) -> Callable[[_TypeT], _TypeT]

一个便捷的装饰器,用于在标准库中的 TypedDictdataclass 上设置 Pydantic 配置

尽管可以使用 __pydantic_config__ 属性设置配置,但它与类型检查器配合不佳,尤其是与 TypedDict 配合使用时。

用法

from typing_extensions import TypedDict

from pydantic import ConfigDict, TypeAdapter, with_config

@with_config(ConfigDict(str_to_lower=True))
class TD(TypedDict):
    x: str

ta = TypeAdapter(TD)

print(ta.validate_python({'x': 'ABC'}))
#> {'x': 'abc'}
源代码位于 pydantic/config.py
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
def with_config(config: ConfigDict | None = None, /, **kwargs: Any) -> Callable[[_TypeT], _TypeT]:
    """!!! abstract "Usage Documentation"
        [Configuration with other types](../concepts/config.md#configuration-on-other-supported-types)

    A convenience decorator to set a [Pydantic configuration](config.md) on a `TypedDict` or a `dataclass` from the standard library.

    Although the configuration can be set using the `__pydantic_config__` attribute, it does not play well with type checkers,
    especially with `TypedDict`.

    !!! example "Usage"

        ```python
        from typing_extensions import TypedDict

        from pydantic import ConfigDict, TypeAdapter, with_config

        @with_config(ConfigDict(str_to_lower=True))
        class TD(TypedDict):
            x: str

        ta = TypeAdapter(TD)

        print(ta.validate_python({'x': 'ABC'}))
        #> {'x': 'abc'}
        ```
    """
    if config is not None and kwargs:
        raise ValueError('Cannot specify both `config` and keyword arguments')

    if len(kwargs) == 1 and (kwargs_conf := kwargs.get('config')) is not None:
        warnings.warn(
            'Passing `config` as a keyword argument is deprecated. Pass `config` as a positional argument instead',
            category=PydanticDeprecatedSince211,
            stacklevel=2,
        )
        final_config = cast(ConfigDict, kwargs_conf)
    else:
        final_config = config if config is not None else cast(ConfigDict, kwargs)

    def inner(class_: _TypeT, /) -> _TypeT:
        # Ideally, we would check for `class_` to either be a `TypedDict` or a stdlib dataclass.
        # However, the `@with_config` decorator can be applied *after* `@dataclass`. To avoid
        # common mistakes, we at least check for `class_` to not be a Pydantic model.
        from ._internal._utils import is_model_class

        if is_model_class(class_):
            raise PydanticUserError(
                f'Cannot use `with_config` on {class_.__name__} as it is a Pydantic model',
                code='with-config-on-model',
            )
        class_.__pydantic_config__ = final_config
        return class_

    return inner

ExtraValues module-attribute

ExtraValues = Literal['allow', 'ignore', 'forbid']

pydantic.alias_generators

用于在不同大小写约定之间转换的别名生成器。

to_pascal

to_pascal(snake: str) -> str

将 snake_case 字符串转换为 PascalCase。

参数

名称 类型 描述 默认值
snake str

要转换的字符串。

required

返回值

类型 描述
str

PascalCase 字符串。

源代码位于 pydantic/alias_generators.py
12
13
14
15
16
17
18
19
20
21
22
def to_pascal(snake: str) -> str:
    """Convert a snake_case string to PascalCase.

    Args:
        snake: The string to convert.

    Returns:
        The PascalCase string.
    """
    camel = snake.title()
    return re.sub('([0-9A-Za-z])_(?=[0-9A-Z])', lambda m: m.group(1), camel)

to_camel

to_camel(snake: str) -> str

将 snake_case 字符串转换为 camelCase。

参数

名称 类型 描述 默认值
snake str

要转换的字符串。

required

返回值

类型 描述
str

转换后的 camelCase 字符串。

源代码位于 pydantic/alias_generators.py
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def to_camel(snake: str) -> str:
    """Convert a snake_case string to camelCase.

    Args:
        snake: The string to convert.

    Returns:
        The converted camelCase string.
    """
    # If the string is already in camelCase and does not contain a digit followed
    # by a lowercase letter, return it as it is
    if re.match('^[a-z]+[A-Za-z0-9]*$', snake) and not re.search(r'\d[a-z]', snake):
        return snake

    camel = to_pascal(snake)
    return re.sub('(^_*[A-Z])', lambda m: m.group(1).lower(), camel)

to_snake

to_snake(camel: str) -> str

将 PascalCase、camelCase 或 kebab-case 字符串转换为 snake_case。

参数

名称 类型 描述 默认值
camel str

要转换的字符串。

required

返回值

类型 描述
str

snake_case 格式的转换后字符串。

源代码位于 pydantic/alias_generators.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def to_snake(camel: str) -> str:
    """Convert a PascalCase, camelCase, or kebab-case string to snake_case.

    Args:
        camel: The string to convert.

    Returns:
        The converted string in snake_case.
    """
    # Handle the sequence of uppercase letters followed by a lowercase letter
    snake = re.sub(r'([A-Z]+)([A-Z][a-z])', lambda m: f'{m.group(1)}_{m.group(2)}', camel)
    # Insert an underscore between a lowercase letter and an uppercase letter
    snake = re.sub(r'([a-z])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2)}', snake)
    # Insert an underscore between a digit and an uppercase letter
    snake = re.sub(r'([0-9])([A-Z])', lambda m: f'{m.group(1)}_{m.group(2)}', snake)
    # Insert an underscore between a lowercase letter and a digit
    snake = re.sub(r'([a-z])([0-9])', lambda m: f'{m.group(1)}_{m.group(2)}', snake)
    # Replace hyphens with underscores to handle kebab-case
    snake = snake.replace('-', '_')
    return snake.lower()