如何在Pydantic模型中设置动态键以去除接口返回外层包裹字段
解决方案
你遇到的问题核心是原来的Pydantic模型强行嵌套了一层user_id字段,只需要调整模型定义和接口返回逻辑即可,不需要复杂改动。
第一步:调整Pydantic模型定义
首先先定义单个用户的字段校验模型,再处理外层动态键的结构:
# 先定义内层单个用户的结构模型 class SellSideUserItem(_BaseModel): user_name: str user_pass: str class Config: orm_mode = True # 外层动态键模型,根据你用的Pydantic版本二选一即可 ## Pydantic V2 写法:用RootModel from pydantic import RootModel class SellSideUserId(RootModel[dict[str, SellSideUserItem]]): pass ## Pydantic V1 写法:用__root__特殊字段 class SellSideUserId(_BaseModel): __root__: dict[str, SellSideUserItem] class Config: orm_mode = True
如果你不想单独定义外层模型,也可以直接在接口的response_model参数里指定dict[str, SellSideUserItem],可以省掉写RootModel的步骤。
第二步:调整接口返回逻辑
原来的返回逻辑把结果套了一层user_id字段,现在直接把构造好的result传给模型即可:
@app.get('/dealers_get_users/', response_model = schemas.SellSideUserId, status_code=200) def getdata(db: database.SessionLocal = _Depends(database.get_db)): result = {} i = db.query(models.sellSideUser).all() for dealer_users in i: result[str(dealer_users.user_id)] = { 'user_name' : dealer_users.user_name, 'user_pass' : dealer_users.user_pass, } # 直接传入result,不需要套user_id字段 # Pydantic V2写法 return schemas.SellSideUserId(root=result) # Pydantic V1写法,替换上面一行即可 # return schemas.SellSideUserId(__root__=result)
极简写法(不需要定义外层RootModel)
直接在接口指定response_model为字典类型,直接返回result即可,代码更简洁:
@app.get('/dealers_get_users/', response_model = dict[str, schemas.SellSideUserItem], status_code=200) def getdata(db: database.SessionLocal = _Depends(database.get_db)): result = {} i = db.query(models.sellSideUser).all() for dealer_users in i: result[str(dealer_users.user_id)] = { 'user_name' : dealer_users.user_name, 'user_pass' : dealer_users.user_pass, } return result
常见疑问解答
- 是否需要两个嵌套的Pydantic模型?是,至少需要两个结构:一个校验内层单个用户的固定字段,一个处理外层动态键的字典结构,后者可以用RootModel封装,也可以直接在response_model参数里声明类型省略单独定义。
- 之前直接传result报错的原因:原来的
SellSideUserId模型要求入参必须包含名为user_id的字段,你直接传动态键字典没有对应字段,自然会校验失败。
内容的提问来源于stack exchange,提问作者avnav99
相关产品推荐
相关产品推荐

