FastAPI BaseModel字典结构定义及JSON请求适配问题求助
问题:FastAPI BaseModel无法匹配目标JSON结构
目标请求JSON结构
{ "a": [ { "text": "text", "language": "en", "entities": [ { "d": "g" }, { "e": "h" }, { "f": "i" } ] }, { "text": "another text", "language": "en", "entities": [ { "d": "z" } ] } ], "b": [ { "text": "more texts", "language": "en", "entities": [ { "d": "r" }, { "e": "t" }, { "f": "z" } ] } ], "c": ["d", "e", "f"] }
当前FastAPI端点代码
@app.post("/json") def method(a: AModel, b: BModel, c: CModel): # code
当前BaseModel定义
class Input(BaseModel): text: str = Field ( title="A text", example= "text" ) language: str = Field ( default=None, title="A language string", max_length=2, example="en" ) entities: Dict[str, str] = Field ( default=None, title="xxx.", example= [{"d": "x"}, {"f": "y"}] ) class Config: orm_mode=True class CModel (BaseModel): c: List[str] = Field ( title="xxx.", example= ["d", "e", "f"] ) class BModel (BaseModel): b: List[Input] = Field ( title="yyy." ) class AModel (BaseModel): a: List[Input] = Field ( title="zzz." )
返回的错误信息
{ "detail": [ { "loc": [ "body", "trainingdata" ], "msg": "value is not a valid dict", "type": "type_error.dict" }, { "loc": [ "body", "testingdata" ], "msg": "value is not a valid dict", "type": "type_error.dict" }, { "loc": [ "body", "entities" ], "msg": "value is not a valid dict", "type": "type_error.dict" } ] }
问题分析与修正方案
核心问题
- 端点参数解析错误:当前端点将
a、b、c作为独立的BaseModel参数,FastAPI会默认期望这些参数是独立字典或表单数据,但实际请求体是包含三个字段的单一JSON对象,导致解析不匹配。 - entities字段类型不匹配:原JSON中
entities是字典数组([{"d":"g"}, ...]),但模型中定义为Dict[str, str](单一字典),类型完全不符。 - 冗余模型定义:
AModel、BModel、CModel都是仅包裹单个字段的模型,可合并到顶层模型简化结构。
修正后的代码
修正后的BaseModel定义
from pydantic import BaseModel, Field from typing import List, Dict class Input(BaseModel): text: str = Field(title="A text", example="text") language: str = Field(default=None, title="A language string", max_length=2, example="en") # 修改entities为字典数组,匹配JSON结构,支持任意键值对 entities: List[Dict[str, str]] = Field(default=None, title="实体列表", example=[{"d": "x"}, {"f": "y"}]) class Config: orm_mode = True # 顶层模型,直接对应整个请求体的结构 class RequestBody(BaseModel): a: List[Input] = Field(title="zzz.") b: List[Input] = Field(title="yyy.") c: List[str] = Field(title="xxx.", example=["d", "e", "f"])
修正后的端点代码
@app.post("/json") def method(request_body: RequestBody): # 通过request_body.a、request_body.b、request_body.c访问对应数据 return {"received_data": request_body.dict()}
说明
- 顶层
RequestBody模型直接映射整个请求体的JSON结构,让FastAPI正确解析单一JSON对象。 Input中的entities改为List[Dict[str, str]],既匹配JSON中的数组结构,又支持任意不确定的键值对,满足不能硬编码键的需求。- 移除冗余的
AModel、BModel、CModel,简化代码结构。
内容的提问来源于stack exchange,提问作者AnnemarieWittig
相关产品推荐
相关产品推荐

