You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Pydantic V2模型在特定场景下所有字段均为必填

实现Pydantic v2模型的动态严格模式(禁用默认值)

方案1:通过Context参数+根验证器实现动态控制

可以利用model_validate的context传入开关,结合根验证器检查所有字段是否被显式传入——严格模式下,无论字段是否有默认值,都必须在输入中提供。

from pydantic import BaseModel, ValidationError, model_validator
from typing import Dict, Any

class User(BaseModel):
    name: str
    age: int = 18
    email: str = "default@example.com"

    @model_validator(mode="before")
    def check_strict_mode(cls, data: Dict[str, Any], info) -> Dict[str, Any]:
        # 从context中读取严格模式开关,默认关闭
        strict_mode = info.context.get("strict_mode", False)
        if strict_mode:
            all_fields = cls.model_fields.keys()
            missing_fields = [field for field in all_fields if field not in data]
            if missing_fields:
                raise ValueError(f"严格模式下必须传入以下字段: {', '.join(missing_fields)}")
        return data

# 正常模式:可省略带默认值的字段
normal_user = User.model_validate({"name": "Alice"})
print(normal_user)  # name='Alice' age=18 email='default@example.com'

# 严格模式:缺少字段会触发报错
try:
    strict_user = User.model_validate({"name": "Bob"}, context={"strict_mode": True})
except ValidationError as e:
    print(e.errors())  # 提示缺少age和email字段

# 严格模式下传入所有字段则正常通过
strict_user_ok = User.model_validate(
    {"name": "Bob", "age": 25, "email": "bob@example.com"},
    context={"strict_mode": True}
)
print(strict_user_ok)  # name='Bob' age=25 email='bob@example.com'

方案2:自定义基类封装逻辑(更低样板代码)

如果多个模型都需要严格模式功能,可封装一个基类把验证逻辑统一实现,其他模型直接继承即可:

from pydantic import BaseModel, model_validator
from typing import Dict, Any

class StrictModeBaseModel(BaseModel):
    @model_validator(mode="before")
    def check_strict_mode(cls, data: Dict[str, Any], info) -> Dict[str, Any]:
        strict_mode = info.context.get("strict_mode", False)
        if strict_mode:
            all_fields = cls.model_fields.keys()
            missing_fields = [f for f in all_fields if f not in data]
            if missing_fields:
                raise ValueError(f"严格模式下必须传入字段: {', '.join(missing_fields)}")
        return data

# 继承基类后自动获得严格模式能力
class Product(StrictModeBaseModel):
    id: str
    name: str = "Unnamed"
    price: float = 0.0

# 使用方式一致
try:
    Product.model_validate({"id": "123"}, context={"strict_mode": True})
except ValueError as e:
    print(e)  # 严格模式下必须传入字段: name, price

注意事项

  • 上述方案在验证前置阶段(mode="before")检查字段完整性,确保默认值不会被自动填充。
  • Pydantic v2目前没有内置的全局开关直接禁用所有默认值,上述两种方式是低样板代码的可行实现。

内容的提问来源于stack exchange,提问作者user1894205

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:33:24