FastAPI使用空Depends()时Pydantic field_validator失效问题
问题原因
当你通过FastAPI的Depends(YourModel)处理包含文件上传的请求时,FastAPI会将模型拆解为表单字段逐个解析。对于Enum类型的字段,FastAPI默认会直接尝试将表单传入的字符串转换为Enum实例——此时如果传入的是Enum的名称(而非定义的value值),转换会直接失败。
而你的自定义field_validator默认是mode="after"(Pydantic v2默认行为),即验证器会在字段完成类型转换后才运行。这就导致类型转换失败时,验证器根本没机会执行,直接返回参数无效的错误。
但直接实例化模型时,Pydantic会完整执行从参数解析到验证的全流程,验证器可以正常拦截并处理Enum名称的转换,所以不会报错。
解决方案
关键是调整验证器的运行时机,让它在类型转换之前执行,提前将传入的Enum名称转换为对应的Enum实例。有两种实现方式:
方式1:修改field_validator的mode参数
给field_validator添加mode="before"参数,确保验证器在字段类型转换前触发:
from fastapi import FastAPI, UploadFile, Depends from enum import Enum from pydantic import BaseModel, field_validator app = FastAPI() class ItemType(str, Enum): IMAGE = "img" VIDEO = "vid" class UploadRequest(BaseModel): type: ItemType files: list[UploadFile] @field_validator("type", mode="before") def parse_type_from_name_or_value(cls, value): if isinstance(value, str): # 优先匹配Enum名称,再匹配Enum值,支持大小写不敏感 try: return ItemType[value.upper()] except KeyError: return ItemType(value) return value @app.post("/upload") async def upload_files(request: UploadRequest = Depends()): return { "type": request.type.value, "file_count": len(request.files) }
方式2:使用Annotated + BeforeValidator(Pydantic v2推荐)
用Annotated结合BeforeValidator显式声明前置验证逻辑,代码结构更清晰:
from fastapi import FastAPI, UploadFile, Depends from enum import Enum from pydantic import BaseModel, BeforeValidator from typing import Annotated app = FastAPI() class ItemType(str, Enum): IMAGE = "img" VIDEO = "vid" def parse_item_type(value): if isinstance(value, str): try: return ItemType[value.upper()] except KeyError: return ItemType(value) return value class UploadRequest(BaseModel): type: Annotated[ItemType, BeforeValidator(parse_item_type)] files: list[UploadFile] @app.post("/upload") async def upload_files(request: UploadRequest = Depends()): return { "type": request.type.value, "file_count": len(request.files) }
这两种方式都能让传入的Enum名称(比如"IMAGE")被正确转换为对应的Enum实例,同时兼容原本的Enum值(比如"img")传入,无需依赖自定义的辅助函数。
内容的提问来源于stack exchange,提问作者maggie
相关产品推荐
相关产品推荐

