FastAPI嵌套数据模型GET方法获取数据时ValidationError问题求助
问题解决方案
错误原因
MongoDB中存储的_id是ObjectId类型,而你的Pydantic模型Case里定义的id是str类型,直接返回case["_id"]会导致类型不匹配,触发ValidationError。另外你的listCases函数里存在笔误,调用了未定义的clinicalCase函数,应该是practicalCase。
修复步骤
1. 修正practicalCase函数,将ObjectId转为字符串
修改practicalCase函数,把case["_id"]转换为字符串类型:
def practicalCase(case) -> dict: return { "id": str(case["_id"]), # 将ObjectId转为字符串 "description": case["description"], "menu": case["menu"] }
2. 修正listCases函数的笔误
把函数内的clinicalCase改为practicalCase:
def listCases(entity) -> list: return [practicalCase(case) for case in entity]
3. 完善POST接口的返回逻辑
你的new_case接口最后没有正确返回数据,需要返回转换后的case对象:
@case.post('/newcases', response_model=Case, tags=["case"]) async def new_case(case: Case): case_new = dict(case) del case_new["id"] json_compatible_item_data = jsonable_encoder(case_new) id = ven.local.cases.insert_one(json_compatible_item_data).inserted_id # 查询并转换返回格式 inserted_case = ven.local.cases.find_one({"_id": id}) return practicalCase(inserted_case)
额外优化建议
如果希望更优雅地处理MongoDB的ObjectId和Pydantic模型的映射,可以在Pydantic模型中配置自动转换规则:
from bson import ObjectId from pydantic import BaseModel, Field from typing import Optional, List # 自定义ObjectId的Pydantic类型 class PyObjectId(ObjectId): @classmethod def __get_validators__(cls): yield cls.validate @classmethod def validate(cls, v): if not ObjectId.is_valid(v): raise ValueError("Invalid ObjectId") return ObjectId(v) @classmethod def __modify_schema__(cls, field_schema): field_schema.update(type="string") # 修改Case模型的id字段配置 class Case(BaseModel): id: PyObjectId = Field(default_factory=PyObjectId, alias="_id") description: str menu: List[Menu] class Config: allow_population_by_field_name = True json_encoders = {ObjectId: str}
这样配置后,Pydantic会自动处理ObjectId和字符串的双向转换,无需手动在practicalCase函数中转换_id。
内容的提问来源于stack exchange,提问作者EnriqueLB
相关产品推荐
相关产品推荐

