跳转到内容

严格模式

API 文档

pydantic.types.Strict

默认情况下,Pydantic 会在可能的情况下尝试将值强制转换为所需的类型。例如,您可以将字符串 '123' 作为 int 整数类型 的输入,它将被转换为值 123。这种强制转换行为在许多场景中都很有用——比如:UUID、URL 参数、HTTP 标头、环境变量、日期等。

然而,在某些情况下,这种行为可能不是我们所期望的,您可能希望 Pydantic 在类型不匹配时报错,而不是强制转换数据。

为了更好地支持这种用例,Pydantic 提供了“严格模式”。当启用严格模式时,Pydantic 在强制转换数据方面会变得不那么宽松,如果数据不是正确的类型,则会报错。

在大多数情况下,严格模式只允许提供该类型的实例,不过对于 JSON 输入可能会应用更宽松的规则(例如,日期和时间类型即使在严格模式下也允许字符串)。

每种类型的严格行为可以在标准库类型文档中找到,并在转换表中进行了总结。

这里有一个简短的例子,展示了在严格模式和默认的宽松模式下验证行为的差异

from pydantic import BaseModel, ValidationError


class MyModel(BaseModel):
    x: int


print(MyModel.model_validate({'x': '123'}))  # lax mode
#> x=123

try:
    MyModel.model_validate({'x': '123'}, strict=True)  # strict mode
except ValidationError as exc:
    print(exc)
    """
    1 validation error for MyModel
    x
      Input should be a valid integer [type=int_type, input_value='123', input_type=str]
    """

严格模式可以通过多种方式启用

作为验证参数

当在 Pydantic 模型类型适配器上使用验证方法时,可以基于每次验证调用来启用严格模式。

from datetime import date

from pydantic import TypeAdapter, ValidationError

print(TypeAdapter(date).validate_python('2000-01-01'))  # OK: lax
#> 2000-01-01

try:
    # Not OK: strict:
    TypeAdapter(date).validate_python('2000-01-01', strict=True)
except ValidationError as exc:
    print(exc)
    """
    1 validation error for date
      Input should be a valid date [type=date_type, input_value='2000-01-01', input_type=str]
    """

TypeAdapter(date).validate_json('"2000-01-01"', strict=True)  # (1)!
#> 2000-01-01
  1. 如前所述,从 JSON 验证时,严格模式会更宽松。

在字段级别

可以通过将 Field() 函数的 strict 参数设置为 True,在特定字段上启用严格模式。即使在宽松模式下调用验证方法,这些字段也将应用严格模式。

from pydantic import BaseModel, Field, ValidationError


class User(BaseModel):
    name: str
    age: int = Field(strict=True)  # (1)!


user = User(name='John', age=42)
print(user)
#> name='John' age=42


try:
    another_user = User(name='John', age='42')
except ValidationError as e:
    print(e)
    """
    1 validation error for User
    age
      Input should be a valid integer [type=int_type, input_value='42', input_type=str]
    """
  1. 严格约束也可以使用注解模式来应用:Annotated[int, Field(strict=True)]

使用 Strict() 元数据类

API 文档

pydantic.types.Strict

作为 Field() 函数的替代方案,Pydantic 提供了 Strict 元数据类,旨在与注解模式一起使用。它还为最常见的类型提供了方便的别名(即 StrictBoolStrictIntStrictFloatStrictStrStrictBytes)。

from typing import Annotated
from uuid import UUID

from pydantic import BaseModel, Strict, StrictInt


class User(BaseModel):
    id: Annotated[UUID, Strict()]
    age: StrictInt  # (1)!
  1. 等同于 Annotated[int, Strict()]

作为配置值

严格模式行为可以在配置级别进行控制。当在 Pydantic 模型(或像 dataclasses 这样的类模型)上使用时,严格性仍然可以在字段级别被覆盖。

from pydantic import BaseModel, ConfigDict, Field


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

    name: str
    age: int = Field(strict=False)


print(User(name='John', age='18'))
#> name='John' age=18