严格模式
API 文档
默认情况下,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 模型上使用
model_validate()
等方法时,作为验证参数传入。 - 在字段级别.
- 在配置级别设置(并可能在字段级别覆盖)。
作为验证参数¶
当在 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
- 如前所述,从 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]
"""
- 严格约束也可以使用注解模式来应用:
Annotated[int, Field(strict=True)]
使用 Strict()
元数据类¶
API 文档
作为 Field()
函数的替代方案,Pydantic 提供了 Strict
元数据类,旨在与注解模式一起使用。它还为最常见的类型提供了方便的别名(即 StrictBool
、StrictInt
、StrictFloat
、StrictStr
和 StrictBytes
)。
from typing import Annotated
from uuid import UUID
from pydantic import BaseModel, Strict, StrictInt
class User(BaseModel):
id: Annotated[UUID, Strict()]
age: StrictInt # (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