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

Pydantic中某字段校验失败时如何跳过其余字段的验证?

Pydantic 核心字段校验失败终止后续流程的原生实现方案

Pydantic v2(推荐升级)

v2版本原生提供了校验终止的配置项,直接在模型配置中指定validation_stop为FIRST_ERROR即可实现第一个错误出现后直接终止所有后续校验,不会触发后续校验逻辑,同时错误定位正常指向具体出错字段。

from pydantic import BaseModel, field_validator, ValidationStop
from myapp import User
from typing import Any

class ChangePasswordRequest(BaseModel):
    model_config = {
        "arbitrary_types_allowed": True,
        # 第一个校验错误出现就终止全部后续校验流程
        "validation_stop": ValidationStop.FIRST_ERROR
    }

    # 核心字段放在最前优先校验
    user: User
    current_password: str
    new_password: str
    
    @field_validator("user")
    def user_is_active(cls, user: User):
        if user.inactive:
            raise ValueError("User is not active.")
        return user

    @field_validator("current_password")
    def current_password_validator(cls, password: str, values: dict[str, Any]):
        user: User = values["user"]
        if not user.check_password(password):
            raise ValueError("current_password is not valid.")
        return password

Pydantic v1 兼容方案

v1没有全局终止校验的原生配置,但可以通过以下两种方式实现需求,无需为每个校验器额外加判断逻辑:

方案1:主动抛出指定定位的ValidationError

Pydantic v1的字段校验按定义顺序执行,核心字段放在最前面定义,校验失败时主动抛出带字段定位的ValidationError,会直接终止整个校验流程:

from pydantic import BaseModel, validator, ValidationError
from myapp import User

class ChangePasswordRequest(BaseModel):
    class Config:
        arbitrary_types_allowed = True

    # 核心字段优先定义
    user: User
    current_password: constr(min_length=1, max_length=255)
    new_password: constr(min_length=8, max_length=64)
    
    @validator("user")
    def user_is_active(cls, user: User):
        if user.inactive:
            raise ValidationError(
                errors=[{
                    "loc": ["user"],
                    "msg": "User is not active.",
                    "type": "value_error"
                }],
                model=cls
            )
        return user

    @validator("current_password")
    def current_password_validator(cls, password: str, values: dict):
        user: User = values["user"]
        if not user.check_password(password):
            raise ValueError("current_password is not valid.")
        return password

方案2:root_validator 自定义错误定位

如果用root_validator的方案,只需主动构造错误信息指定loc字段,即可解决错误指向__root__的问题:

from pydantic import BaseModel, root_validator, ValidationError
from myapp import User

class ChangePasswordRequest(BaseModel):
    class Config:
        arbitrary_types_allowed = True

    user: User
    current_password: constr(min_length=1, max_length=255)
    new_password: constr(min_length=8, max_length=64)
    
    @root_validator(pre=True)
    def check_user_status(cls, values):
        user = values.get("user")
        if not user or user.inactive:
            raise ValidationError(
                errors=[{
                    "loc": ["user"],
                    "msg": "User is not active.",
                    "type": "value_error"
                }],
                model=cls
            )
        return values

注意:不要使用assert编写校验逻辑,Python运行时开启优化模式(添加-O参数)时,所有assert语句会被全局移除,导致校验逻辑失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 01:51:03