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

FastAPI中如何返回文件验证与其他字段的全部校验错误?

问题:如何将文件验证错误与其他字段校验错误一并返回

实际需求并非实现文件大小/扩展名验证,而是要让文件验证错误能和其他字段的校验错误一起返回,具体分为以下两个问题:

要点1:依赖注入方式下的批量错误返回问题

当前实现代码如下:

app = FastAPI()


class FileExtensionValidator:
    message = 'Extension “{extension}” not allowed. Allowed extensions are {allowed_extensions}'

    def __init__(self, allowed_extensions=None, message=None):
        if allowed_extensions is not None:
            allowed_extensions = [allowed_extension.lower() for allowed_extension in allowed_extensions]
        self.allowed_extensions = allowed_extensions
        if message is not None:
            self.message = message

    def __call__(self, file: UploadFile):
        extension = Path(file.filename).suffix[1:].lower()
        if self.allowed_extensions is not None and extension not in self.allowed_extensions:
            detail = self.message.format(extension=extension, allowed_extensions=', '.join(self.allowed_extensions))
            raise HTTPException(400, detail=detail)


class MaxFileSizeMBValidator:
    def __init__(self, max_mb: int):
        self.max_mb = max_mb

    def __call__(self, file: UploadFile):
        if file.size / 1024 / 1024 > self.max_mb:
            message = f'Maximum file size exceeded'
            raise HTTPException(400, detail=message)


@router.post(
    '/upload/',
    dependencies=[
        Depends(MaxFileSizeMBValidator(max_mb=1)),
        Depends(FileExtensionValidator(allowed_extensions=['.docx'])),
    ]
)
async def upload_file(file: UploadFile, user_id: int = Form()):
    return {'filename': file.filename}

上述代码无法返回全部校验错误:比如上传.csv文件且未传入必填字段user_id时,FastAPI仅返回单个错误:

{
    "detail": "Extension “csv” not allowed. Allowed extensions are .docx"
}

但期望同时返回所有错误,格式如下:

{
    "detail": [
        {
            "loc": [
                "body",
                "file"
            ],
            "msg": "Extension “csv” not allowed. Allowed extensions are .docx",
            "type": "value_error.missing"
        },
        {
            "loc": [
                "body",
                "user_id"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

需求:如何实现上述批量错误返回?若采用依赖注入方式,该如何调整校验逻辑?要求保持验证器独立,可按需调用。

要点2:自定义UploadFile类的灵活性优化问题

通过重写UploadFile类可以实现验证:

class CustomUploadFile(UploadFile):
    validators = [
        MaxFileSizeMBValidator(max_mb=10),
        FileExtensionValidator(allowed_extensions=['.docx']),
    ]

    @classmethod
    def __get_validators__(cls: Type["UploadFile"]) -> Iterable[Callable[..., Any]]:
        yield cls.validate
        
        for validator in cls.validators:
            yield validator

但这种方式灵活性不足,每次更换验证器都需要重新子类化,寻求更优实现方案。


内容的提问来源于stack exchange,提问作者Альберт Александров

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:07:36