Pydantic模型报错:Input should be a valid dictionary or object问题求助
问题:Post API的Pydantic模型报错"Input should be a valid dictionary or object to extract fields from"
我在为Post API创建Pydantic模型时遇到如下错误:
Input should be a valid dictionary or object to extract fields from
尝试修改类型定义及模型配置后仍未解决,以下是相关代码和错误追踪信息,请求分析报错原因:
模型代码
from typing import List from fastapi import UploadFile, File, Form, Depends from pydantic import BaseModel, Field class Types(BaseModel): categoryid: str = Field() categoryname: str = Field() subcategoryid: str = Field() subcategoryname: str = Field() class Config: from_attributes = True populate_by_name = True arbitrary_types_allowed = False class Availability(BaseModel): quantity: int = Form(...) size: str = Form(...) price: str = Form(...) class Config: from_attributes = True populate_by_name = True arbitrary_types_allowed = False class ProductUnits(BaseModel): color: str = Form(...) image: str = Form(...) # availability: List[Availability] = Depends() class Product(BaseModel): # productname: Optional[str] = None # minorder: Optional[int] = None # producttype: Types = Depends() # productdetails: Optional[str] = None productunits: List[ProductUnits] # shippingtime: Optional[str] = None # cod: Optional[bool] = None # codminimumamt: Optional[int] = None # returnpolicy: Optional[str] = None productimages: list[UploadFile] = File(...)
路由代码
from fastapi import APIRouter, Request, status, Depends from src.products.models import Product from src.utils.statuscode import statuscode productrouter = APIRouter() @productrouter.post("/", response_description="Create a products", status_code=status.HTTP_201_CREATED, ) async def create_product(request: Request, product: Product = Depends()): print(product) return statuscode(status=True, message='Product added Successfully')
错误追踪信息
{ "detail": [ { "type": "model_attributes_type", "loc": [ "body", "productunits", 0 ], "msg": "Input should be a valid dictionary or object to extract fields from", "input": "{\r\n \"color\": \"string\",\r\n \"image\": \"string\"\r\n}", "url": "https://errors.pydantic.dev/2.4/v/model_attributes_type" } ] }
报错原因分析
核心问题是错误地在Pydantic模型字段中混用了FastAPI的Form依赖项,同时处理文件上传和嵌套JSON数据的方式不符合FastAPI的解析规则:
Form与嵌套模型冲突:ProductUnits的字段用了Form(...),但productunits是嵌套的JSON数组类型,Form仅用于解析表单数据,无法适配JSON结构体的解析,导致FastAPI把数组元素当成字符串而非字典。- 文件与JSON请求体无法同时解析:
Product中包含UploadFile类型的productimages,当用Depends()解析整个模型时,FastAPI无法同时处理multipart/form-data(文件上传)和application/json(嵌套JSON)两种请求格式,导致输入解析混乱。
解决方案
方案1:用multipart/form-data传递JSON字符串+文件
如果需要单请求同时上传文件和提交结构化数据,可将嵌套的JSON字段以字符串形式传递,再在模型中解析:
- 修改模型,移除
Form依赖,添加JSON解析逻辑:
from typing import List from fastapi import UploadFile, File, Form from pydantic import BaseModel, model_validator import json class ProductUnits(BaseModel): color: str image: str class Product(BaseModel): productunits: List[ProductUnits] productimages: list[UploadFile] = File(...) @model_validator(mode='before') def parse_productunits(cls, values): # 将表单中的JSON字符串解析为字典列表 if isinstance(values.get('productunits'), str): values['productunits'] = json.loads(values['productunits']) return values
- 调整路由,直接用模型接收表单数据:
@productrouter.post("/", response_description="Create a products", status_code=status.HTTP_201_CREATED) async def create_product(product: Product = Form(...)): print(product) return statuscode(status=True, message='Product added Successfully')
请求时使用multipart/form-data格式,productunits字段传入JSON字符串(比如[{"color":"red","image":"url"}]),productimages上传文件。
方案2:拆分请求(更简洁)
如果业务允许,可拆分两次请求:
- 先提交产品的结构化数据(JSON格式),获取产品ID;
- 单独上传产品图片,关联到对应的产品ID。
注意事项
- Pydantic模型字段不要使用
Form、File这类FastAPI依赖项,这些是用于路由参数解析的,模型字段应使用普通类型(如str、int)定义。 from_attributes等模型配置仅用于从ORM对象实例化模型,和请求参数解析无关,可保留但不影响当前问题。
内容的提问来源于stack exchange,提问作者picture talks
相关产品推荐
相关产品推荐

