如何为FastAPI的Pydantic模型实现字段间依赖验证?
解决方案
你可以通过Pydantic的模型验证器实现这个自定义规则,以下是具体实现方式:
Pydantic v2 版本(推荐)
使用@model_validator(mode='after')装饰器,在字段基础验证完成后执行自定义逻辑:
from pydantic import BaseModel, ValidationError, model_validator from typing import List, Optional class RequestModel(BaseModel): types: List[str] segments: Optional[List[str]] = [] @model_validator(mode='after') def check_segments_validity(self) -> 'RequestModel': # 当segments包含元素时,强制要求types长度必须为1 if self.segments and len(self.types) != 1: raise ValueError( "segments仅能在types列表长度为1时包含元素" ) return self
逻辑说明
mode='after'确保验证器在所有字段的基础验证(比如类型检查)完成后运行,此时self.types和self.segments已经是合法的列表类型。- 当
segments非空(默认是空列表,if self.segments即可判断是否有元素)且types长度不等于1时,抛出ValueError,Pydantic会自动将其转换为标准的验证错误返回给FastAPI。
Pydantic v1 版本兼容写法
如果你还在使用Pydantic v1,需要用@root_validator(skip_on_failure=True):
from pydantic import BaseModel, ValidationError, root_validator from typing import List, Optional class RequestModel(BaseModel): types: List[str] segments: Optional[List[str]] = [] @root_validator(skip_on_failure=True) def check_segments_validity(cls, values): types = values.get('types') segments = values.get('segments', []) if segments and len(types) != 1: raise ValueError( "segments仅能在types列表长度为1时包含元素" ) return values
测试示例
# 合法请求:types长度为1,segments有元素 valid_req = RequestModel(types=["image"], segments=["thumbnail", "original"]) print(valid_req) # 正常输出 # 非法请求:types长度大于1,segments有元素 try: invalid_req = RequestModel(types=["image", "video"], segments=["thumbnail"]) except ValidationError as e: print(e.errors()) # 输出验证错误详情,包含自定义提示信息
内容的提问来源于stack exchange,提问作者abdulaziz ibrahim
相关产品推荐
相关产品推荐

