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

使用Pydantic验证JSON遇字段验证器错误,需在subject类获取grade

问题解决步骤

1. 修复 ConfigError: Validators defined with incorrect fields: validate_grade 错误

这个错误的核心原因是你定义的Grade类仅添加了字段验证器,但未声明对应的grade字段。Pydantic要求验证器必须绑定到类中已定义的字段上,同时验证器必须返回处理后的值(否则会将字段值置为None)。

修正后的Grade类(如果需要单独定义):

from pydantic import BaseModel, validator

class Grade(BaseModel):
    # 必须先声明对应的字段,验证器才能绑定
    grade: str

    @validator("grade")
    def validate_grade(cls, val):
        if val is None:
            raise ValueError("grade is null")
        # 验证器必须返回值,否则字段会被设为None
        return val

2. 修正JSON语法错误

你的JSON数据存在两处语法问题:

  • "grade": "A" 末尾缺少逗号
  • subject 数组内的对象多了一个闭合大括号

修正后的JSON:

{
  "grade": "A",
  "subject": [
    {
      "physics": "PHY",
      "chemistry": "CHE",
      "classTime": {
        "date": "2024-03-25",
        "time": null
      },
      "labTime": null
    }
  ]
}

3. 在Subject类中获取grade字段的解决方案

由于Subject是嵌套在顶层数据中的子模型,默认无法直接访问父级的grade字段。可以通过顶层模型的全局验证器实现,将grade和subject结合验证:

完整代码示例

from pydantic import BaseModel, validator, root_validator
from typing import List, Optional

class Subject(BaseModel):
    physics: str
    chemistry: str
    classTime: dict
    labTime: Optional[dict] = None

    @validator("classTime", pre=True, always=True)
    def validate_classTime(cls, value):
        date_str = value.get('date', '')
        time_str = value.get('time', '')
        # 添加classTime的验证逻辑,比如检查日期非空
        if not date_str:
            raise ValueError("classTime date cannot be empty")
        return value

# 定义顶层模型,包含整个JSON的结构
class Report(BaseModel):
    grade: str
    subject: List[Subject]

    @validator("grade")
    def validate_grade(cls, val):
        if val is None:
            raise ValueError("grade is null")
        return val

    @root_validator(skip_on_failure=False)
    def validate_subject_with_grade(cls, values):
        # 从values中同时获取grade和subject数据
        grade = values.get("grade")
        subjects = values.get("subject")
        
        if subjects and grade:
            # 这里可以根据grade值对每个subject做自定义验证
            # 示例:如果grade为"A",检查labTime是否为空(可根据需求调整逻辑)
            for subj in subjects:
                if grade == "A" and subj.labTime is not None:
                    raise ValueError(f"Grade A should have no lab time for subject {subj.physics}")
        
        return values

# 测试解析JSON
test_json = {
  "grade": "A",
  "subject": [
    {
      "physics": "PHY",
      "chemistry": "CHE",
      "classTime": {
        "date": "2024-03-25",
        "time": null
      },
      "labTime": null
    }
  ]
}

report = Report(**test_json)
print(report.dict())

说明

  • 顶层模型Report承载了整个JSON的结构,通过root_validator可以同时获取grade和subject数据,实现跨字段的关联验证。
  • 如果使用Pydantic v2,可以将root_validator替换为model_validator(mode='after'),用法逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 16:52:33