跳转到内容

配置

Pydantic 模型的配置。

ConfigDict

基类:TypedDict

用于配置 Pydantic 行为的 TypedDict。

title 实例属性

title: str | None

生成的 JSON 模式的标题,默认为模型的名称。

model_title_generator 实例属性

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

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

field_title_generator 实例属性

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

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

str_to_lower 实例属性

str_to_lower: bool

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

str_to_upper 实例属性

str_to_upper: bool

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

str_strip_whitespace 实例属性

str_strip_whitespace: bool

是否去除字符串类型的前导和尾随空格。

str_min_length 实例属性

str_min_length: int

字符串类型的最小长度。默认为 None

str_max_length 实例属性

str_max_length: int | None

字符串类型的最大长度。默认为 None

extra 实例属性

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__ 方法的参数被包含。

除了在模型上指定 extra 配置值之外,您还可以将其作为参数提供给验证方法。这将覆盖模型上设置的任何 extra 配置值

from pydantic import BaseModel, ConfigDict, ValidationError

class Model(BaseModel):
    x: int
    model_config = ConfigDict(extra="allow")

try:
    # Override model config and forbid extra fields just this time
    Model.model_validate({"x": 1, "y": 2}, extra="forbid")
except ValidationError as exc:
    print(exc)
    """
    1 validation error for Model
    y
      Extra inputs are not permitted [type=extra_forbidden, input_value=2, input_type=int]
    """

frozen 实例属性

frozen: bool

模型是否为假不可变,即是否允许 __setattr__,并且还为模型生成 __hash__() 方法。这使得模型的实例在所有属性都可哈希的情况下可能可哈希。默认为 False

注意

在 V1 中,此设置的反面称为 allow_mutation,默认为 True

populate_by_name 实例属性

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_field='foo')  # (3)!
print(m)
#> my_field='foo'
  1. 字段 'my_field' 有一个别名 'my_alias'
  2. 模型通过别名 'my_alias' 填充。
  3. 模型通过属性名 'my_field' 填充。

use_enum_values 实例属性

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 实例属性

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 实例属性

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 实例属性

from_attributes: bool

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

loc_by_alias 实例属性

loc_by_alias: bool

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

alias_generator 实例属性

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 实例属性

ignored_types: tuple[type, ...]

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

allow_inf_nan 实例属性

allow_inf_nan: bool

是否允许浮点数和 Decimal 字段包含无穷大 (+inf-inf) 和 NaN 值。默认为 True

json_schema_extra 实例属性

json_schema_extra: JsonDict | JsonSchemaExtraCallable | None

一个字典或可调用对象,用于提供额外的 JSON 模式属性。默认为 None

json_encoders 实例属性

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

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

已弃用

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

strict 实例属性

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 实例属性

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 实例属性

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

JSON 序列化时间增量(timedeltas)的格式。接受字符串值 'iso8601''float'。默认为 'iso8601'

  • 'iso8601' 将时间增量序列化为 ISO 8601 文本格式
  • 'float' 将时间增量序列化为总秒数。

警告

从 v2.12 开始,建议使用 ser_json_temporal 设置而不是 ser_json_timedelta。此设置将在 v3 中弃用。

ser_json_temporal 实例属性

ser_json_temporal: Literal[
    "iso8601", "seconds", "milliseconds"
]

datetime 模块中 JSON 序列化时间类型(temporal types)的格式。这包括

可以是以下之一

  • 'iso8601' 将日期类型序列化为 ISO 8601 文本格式
  • 'milliseconds' 将日期类型序列化为自纪元以来的浮点毫秒数。
  • 'seconds' 将日期类型序列化为自纪元以来的浮点秒数。

默认为 'iso8601'

注意

此设置在 v2.12 中引入。它与 ser_json_timedelta 设置重叠,后者将在 v3 中弃用。它还为其他时间类型增加了更多的可配置性。

val_temporal_unit 实例属性

val_temporal_unit: Literal[
    "seconds", "milliseconds", "infer"
]

用于验证日期时间类类型(datetime.datetimedatetime.date)的数字输入时假定的单位。可以是以下之一

  • 'seconds' 将日期或时间数字输入验证为自 纪元 以来的秒数。
  • 'milliseconds' 将日期或时间数字输入验证为自 纪元 以来的毫秒数。
  • 'infer' 将根据 unix 时间的字符串数字输入推断单位,如下所示

    • 如果 \(-2^{10} <= v <= 2^{10}\),则为自 纪元 以来的秒数
    • 如果 \(v < -2^{10}\)\(v > 2^{10}\),则为自 纪元 以来的毫秒数)。

默认为 'infer'

ser_json_bytes 实例属性

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

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

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

val_json_bytes 实例属性

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

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

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

ser_json_inf_nan 实例属性

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

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

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

validate_default 实例属性

validate_default: bool

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

validate_return 实例属性

validate_return: bool

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

protected_namespaces 实例属性

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 自己的方法之间发生冲突。这在 v2.10 中进行了更改,因为有反馈称此限制在 AI 和数据科学环境中具有限制性,在这些环境中,字段名称(如 model_idmodel_inputmodel_output 等)很常见。

有关更多详细信息,请参阅 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' conflicts with protected namespace 'model_dump'.

    You may be able to solve this by setting the 'protected_namespaces' configuration to ('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' conflicts with protected namespace 'also_protect_'.
    You may be able to solve this by setting the 'protected_namespaces' configuration to ('protect_me_', re.compile('^protect_this$'))`.

    Field 'protect_this' in 'Model' conflicts with protected namespace 're.compile('^protect_this$')'.
    You may be able to solve this by setting the 'protected_namespaces' configuration to ('protect_me_', 'also_protect_')`.
    '''

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

from pydantic import BaseModel, ConfigDict

try:

    class Model(BaseModel):
        model_validate: str

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

except ValueError 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 实例属性

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 实例属性

defer_build: bool

是否将模型验证器和序列化器构建推迟到第一次模型验证。默认为 False。

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

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

plugin_settings 实例属性

plugin_settings: dict[str, object] | None

一个用于插件设置的 dict。默认为 None

schema_generator 实例属性

schema_generator: type[GenerateSchema] | None

警告

schema_generator 在 v2.10 中已弃用。

在 v2.10 之前,此设置被宣传为高度可能发生变化。一旦内部核心模式生成 API 更加稳定,此接口可能再次公开,但这很可能在进行了显著的性能改进之后。

json_schema_serialization_defaults_required 实例属性

json_schema_serialization_defaults_required: bool

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

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

但是,在某些情况下这可能是不希望的——特别是,如果您想在验证和序列化之间共享模式,并且不介意具有默认值的字段在序列化期间被标记为非必需。有关更多详细信息,请参阅 #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 实例属性

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

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

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

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

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 实例属性

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 实例属性

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 实例属性

validation_error_cause: bool

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

注意

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

注意

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

use_attribute_docstrings 实例属性

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 和标准库数据类一起使用

由于当前的限制,当使用 TypedDict 和标准库数据类时,属性文档字符串检测可能无法按预期工作,特别是在以下情况下

  • 正在使用继承。
  • 在同一源文件中多个类具有相同的名称(除非使用 Python 3.13 或更高版本)。

cache_strings 实例属性

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

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

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

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

注意

在一般验证期间,需要 True'all' 来缓存字符串,因为验证器不知道它们是在键中还是在值中。

提示

如果重复字符串很少,建议使用 'keys''none' 来减少内存使用,因为如果重复字符串很少,性能差异很小。

validate_by_alias 实例属性

validate_by_alias: bool

是否可以通过其别名填充别名字段。默认为 True

注意

在 v2.11 中,validate_by_aliasvalidate_by_name 一起引入,以使用户能够进行更精细的验证控制。

validate_by_name 实例属性

validate_by_name: bool

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

注意

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

在 v2.11 中,validate_by_namevalidate_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。这将使属性无法填充。

有关示例,请参阅使用错误

serialize_by_alias 实例属性

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_field' 属性的别名 'my_alias' 进行序列化。

url_preserve_empty_path 实例属性

url_preserve_empty_path: bool

在验证 URL 类型的值时是否保留空的 URL 路径。默认为 False

from pydantic import AnyUrl, BaseModel, ConfigDict

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

    url: AnyUrl

m = Model(url='http://example.com')
print(m.url)
#> http://example.com

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]

一个方便的装饰器,用于在 TypedDict 或标准库的 dataclass 上设置 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
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
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 模块属性

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

pydantic.alias_generators

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

to_pascal

to_pascal(snake: str) -> str

将 snake_case 字符串转换为 PascalCase。

参数

名称 类型 描述 默认值
snake str

要转换的字符串。

必需

返回

类型 描述
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

要转换的字符串。

必需

返回

类型 描述
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

要转换的字符串。

必需

返回

类型 描述
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()