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

FastAPI中嵌套Pydantic模型结合文件上传请求报错解决方案咨询

解决FastAPI中嵌套Pydantic模型与文件上传共存的问题

问题原因

当端点包含UploadFile类型参数时,FastAPI会自动将请求的内容类型设为multipart/form-data,但嵌套的Pydantic模型默认期望接收application/json格式的请求体,两者的解析规则冲突,就会出现"Input should be a valid dictionary or object to extract fields from"的错误。

解决方案(保留原有ProcessVideoPayload结构)

方法1:使用Form+JSON手动解析嵌套模型

通过Form接收JSON字符串格式的嵌套模型数据,再手动解析为Pydantic实例:

from fastapi import FastAPI, Form, UploadFile, File
from pydantic import BaseModel
import json

app = FastAPI()

# 原有嵌套模型结构不变
class GenerateVideoModelInfo(BaseModel):
    resolution: str
    duration: int

class ProcessVideoPayload(BaseModel):
    model_info: GenerateVideoModelInfo
    title: str

@app.post("/process-video/")
async def process_video(
    # 用Form接收JSON字符串形式的payload
    payload_json: str = Form(...),
    video_file: UploadFile = File(...),
    extra_param: str = Form("default_value")
):
    # 解析JSON字符串为ProcessVideoPayload实例
    process_payload = ProcessVideoPayload.model_validate_json(payload_json)
    
    # 后续业务逻辑:处理文件和解析后的payload
    return {
        "payload": process_payload.dict(),
        "filename": video_file.filename,
        "extra_param": extra_param
    }

Swagger UI操作方式:在payload_json字段中输入JSON格式的字符串,例如:

{"model_info": {"resolution": "1080p", "duration": 60}, "title": "My Video"}

再上传文件、填写其他参数即可正常请求。

方法2:用Depends封装解析逻辑(更优雅)

把表单解析逻辑封装成依赖类,简化端点代码,适合多端点复用场景:

from fastapi import FastAPI, Depends, UploadFile, File, Form
from pydantic import BaseModel
import json

app = FastAPI()

# 原有嵌套模型结构不变
class GenerateVideoModelInfo(BaseModel):
    resolution: str
    duration: int

class ProcessVideoPayload(BaseModel):
    model_info: GenerateVideoModelInfo
    title: str

# 封装表单解析逻辑的依赖类
class ProcessVideoForm:
    def __init__(
        self,
        payload_json: str = Form(...),
        extra_param: str = Form("default_value")
    ):
        self.payload = ProcessVideoPayload.model_validate_json(payload_json)
        self.extra_param = extra_param

@app.post("/process-video/")
async def process_video(
    form_data: ProcessVideoForm = Depends(),
    video_file: UploadFile = File(...)
):
    # 直接使用解析后的模型实例
    return {
        "payload": form_data.payload.dict(),
        "filename": video_file.filename,
        "extra_param": form_data.extra_param
    }

注意事项

  • 前端请求时,必须将嵌套模型的数据以JSON字符串的形式放在表单字段中,不能单独发送JSON请求体
  • 如果需要同时支持纯JSON和multipart两种请求格式,建议拆分端点,避免增加解析逻辑复杂度

内容的提问来源于stack exchange,提问作者Martina Zapletalová

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 15:43:18