在 pydantic 2 中,`@field_validator` 不再支持 `each_item=true`;若需对 `list[str]` 中每个字符串元素执行预处理(如格式转换),应使用 `beforevalidator` 与 `annotated` 组合,在类型注解层面定义元素级验证逻辑。

在 Pydantic 1 中,@validator(..., each_item=True) 可以便捷地为 List 字段的每个元素调用验证函数。但 Pydantic 2 彻底重构了验证机制:@field_validator 仅作用于整个字段值(即 list 对象本身),不再自动遍历子项。因此,将验证逻辑“下沉”到元素类型层面,是实现逐项处理的标准且推荐做法。

✅ 正确实现方式:使用 BeforeValidator + Annotated

核心思路是:为列表中的每个元素定义带验证的类型别名,再将其用于 List[...] 注解。BeforeValidator 会在每个字符串被解析前单独调用,天然支持“每项独立验证”。

以下是完整、可运行的示例:

复制AI写代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

from pydantic import BaseModel, Field, BeforeValidator

from typing import Annotated, List

def complement_imports(v: str) -> str:

    """将原始模块名转换为 import 语句字符串"""

    if not isinstance(v, str):

        raise TypeError(f"Expected str, got {type(v).__name__}")

    return f'import "{v}"'

# 定义可复用的带验证的元素类型

ImportItem = Annotated[str, BeforeValidator(complement_imports)]

class ComplementQuery(BaseModel):

    imports: List[ImportItem] = Field(default_factory=list)

    subquery: str = Field(...)

# 测试用例

print(ComplementQuery(imports=["a", "b"], subquery="c"))

# 输出: imports=['import "a"', 'import "b"'] subquery='c'

print(ComplementQuery(subquery="c"))

# 输出: imports=[] subquery='c'

⚠️ 常见误区与注意事项

  • ❌ 错误:在 @field_validator("imports", mode="before") 中直接处理 str
    mode="before" 接收的是整个 list(如 ["a", "b"]),而非单个 str;若函数签名写为 def complement_imports(cls, value: str) -> str:,将导致类型错误或逻辑失效。

  • ❌ 错误:将 BeforeValidator 写在 Field(...) 内部(如 Field(default_factory=list, ...))
    Field 的参数不接受验证器;验证器必须通过 Annotated 在类型注解中声明。

  • ✅ 最佳实践:提取验证函数并定义类型别名(如 ImportItem)
    不仅提升可读性与可维护性,还便于在多个字段或模型中复用(例如 exports: List[ImportItem])。

  • ? 补充说明:BeforeValidator 执行时机早于类型转换(如 str → str 本身无转换,但若配合 int 等类型则会先验证后转换),确保业务逻辑前置生效。

总结

Pydantic 2 的验证设计更强调类型即契约:每个数据单元(包括集合中的元素)都应拥有明确、自包含的验证规则。放弃 each_item 并非功能退化,而是推动开发者显式建模数据语义。对于 List[T] 的逐项处理,请始终优先选择 Annotated[T, BeforeValidator(...)] 模式——它精准、安全、符合现代 Pydantic 的哲学,并为未来扩展(如添加 AfterValidator 或 PlainSerializer)预留清晰路径。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐