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

如何在Pydantic的__get_validators__中按顺序调用自定义校验函数

实现方案

你需要为emailId字段定义一个绑定了校验逻辑的自定义类型,在该类型的__get_validators__方法中按你需要的执行顺序yield校验函数即可,校验器的执行顺序和yield顺序完全一致,且前一个校验器的返回值会作为后一个校验器的入参。
具体实现步骤如下:

步骤1:修正原有模型的错误

你原有代码中私有属性_valid_emails的定义有误,先修正:

from pydantic import BaseModel
from typing import List

class PayloadValidator(BaseModel):
    """
    该模型用于校验负载结构和每个负载属性
    """
    tenantId: str
    # 后续会替换为自定义类型
    emailId: List[str]
    role: str
    # 表示负载中的邮箱存在重复
    _duplicates: bool = False
    # 表示负载中的邮箱已被当前请求的租户使用
    _existing:  bool = False
    # 表示负载中的邮箱是非企业邮箱
    _non_corp_emails: bool = False
    # 最终邀请邮箱列表,修正类型标注和默认值
    _valid_emails: List[str] = []

步骤2:定义自定义邮箱列表类型,绑定校验顺序

你需要自定义一个继承自List[str]的类型,在该类型的__get_validators__方法中按你期望的顺序yield校验器,这里我们会把你原有三个业务校验函数包装为符合Pydantic校验规范的方法:

from typing import Any, Dict, List
# 导入你原有三个校验函数
from your_module import email_format, email_existance, duplicate_emails

class ValidatedEmailList(List[str]):
    @classmethod
    def __get_validators__(cls):
        # 按你需要的执行顺序yield校验器,顺序可自行调整
        yield validate_duplicate_emails
        yield validate_email_format
        yield validate_email_existance

步骤3:实现适配Pydantic规范的校验包装函数

Pydantic校验器默认接收当前字段值v、已校验完成的其他字段字典values两个参数,你可以从values中获取tenantId等字段传递给原有业务校验函数:

def validate_duplicate_emails(v: List[str], values: Dict[str, Any]) -> List[str]:
    # 调用原有重复校验函数,根据你函数的实际返回逻辑处理即可
    has_duplicate, processed_emails = duplicate_emails(v)
    # 给模型私有属性赋值
    values["_duplicates"] = has_duplicate
    # 返回处理后的邮箱列表给下一个校验器
    return processed_emails

def validate_email_format(v: List[str], values: Dict[str, Any]) -> List[str]:
    # 调用原有格式校验函数
    is_valid, processed_emails = email_format(v)
    values["_non_corp_emails"] = not is_valid
    return processed_emails

def validate_email_existance(v: List[str], values: Dict[str, Any]) -> List[str]:
    # 从已校验字段中取tenantId传给原有存在性校验函数,剩余参数按你的业务逻辑补充
    tenant_id = values.get("tenantId")
    has_exist, valid_emails = email_existance(v, tenant_id, "你的其他参数")
    values["_existing"] = has_exist
    values["_valid_emails"] = valid_emails
    return v

步骤4:替换模型中emailId的字段类型

将原有PayloadValidator的emailId类型替换为我们定义的ValidatedEmailList即可:

class PayloadValidator(BaseModel):
    """
    该模型用于校验负载结构和每个负载属性
    """
    tenantId: str
    emailId: ValidatedEmailList
    role: str
    _duplicates: bool = False
    _existing:  bool = False
    _non_corp_emails: bool = False
    _valid_emails: List[str] = []

补充说明

  • 如果你原有校验函数遇到非法输入会直接抛出异常,Pydantic会自动捕获异常并转换为标准化的校验错误返回,无需额外处理
  • 校验器的执行顺序完全和__get_validators__中yield的顺序一致,你可以根据业务需求调整yield的先后顺序

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 17:06:04