fastapi: 一个类下包含的model有可能是多种类型j时输出docs文档
一,代码:
说明:
当接口参数ctype为0时,items中列表元素是user
当接口参数ctype为1时,items中列表元素是asset
# 1. 定义 列表 WTForms 表单
# 1. 定义请求体数据模型
class UserListForm(BaseModel):
page: int = Field(default=1, gt=0, description="页数需要大于0")
page_size: int = Field(default=3, gt=0, description="每页数量需要大于0")
ctype: int = Field(default=0, description="0:user,1,asset")
# 输出给前端的用户信息(安全公开,不含密码,包含只读字段)
class UserResponse(BaseModel):
id: int = Field(..., description="用户的唯一ID")
username: str = Field(..., description="用户名")
nickname: str = Field(..., description="用户昵称")
class Config:
from_attributes = True
json_schema_extra = {
"example": {"id": 1, "username": "alex_green", "nickname": "alex@example.com"}
}
# 输出给前端的用户信息(安全公开,不含密码,包含只读字段)
class AssetResponse(BaseModel):
id: int = Field(..., description="资源的唯一ID")
file_name: str = Field(..., description="文件名")
ext: str = Field(..., description="扩展名")
class Config:
from_attributes = True
json_schema_extra = {
"example": {"id": 1, "file_name": "alex_green", "ext": "alex@example.com"}
}
# 这是你需要补上的分页响应模型
class ListPageResponse(BaseModel, Generic[T]):
total: int
# items: List[Union[UserResponse, AssetResponse]] # 核心:这里告诉 Pydantic,items 里面才是用户列表
items: List[T] # 核心:这里告诉 Pydantic,items 里面才是用户列表
@router.get("/all2", response_model=ApiResponse[ListPageResponse[Union[UserResponse, AssetResponse]]], summary="获取商品和用户数据")
async def get_all_users2(request: Request,
prod_data: Annotated[UserListForm, Query()],
db: AsyncSession = Depends(get_db)):
# 参数
page = prod_data.page
page_size = prod_data.page_size
ctype = prod_data.ctype
# 使用 func.count().over() 作为一个隐藏列
stmt = (
select(User, func.count().over().label("total_count"))
.where(User.status == 1)
.offset((page - 1) * page_size)
.limit(page_size)
)
result = await db.execute(stmt)
# 因为多查了一个 count 列,result 出来的每一行是一个元组 (User对象, total_count值)
rows = result.all()
# 解析结果
if not rows:
return {"total": 0, "page": page, "size": page_size, "items": []}
# 无论哪一行,对应的 total_count 都是一样的,取第一行的即可
total = rows[0].total_count
items = [row.User for row in rows]
# 得到assets
stmt_asset = (
select(Asset)
.where(Asset.status == 1)
.order_by(Asset.id.desc())
.limit(2)
)
result_asset = await db.execute(stmt_asset)
# 因为多查了一个 count 列,result 出来的每一行是一个元组 (User对象, total_count值)
asset_items = result_asset.scalars().all()
print("ctype:", ctype)
if ctype == 0:
data = {
"items": items,
"total": total,
}
else:
data = {
"items": asset_items,
"total": 3,
}
return ApiResponse.success(data=data)
说明:
第二种写法:直接在列表中写死类型
# 这是你需要补上的分页响应模型
class ListPageResponse(BaseModel, Generic[T]):
total: int
items: List[Union[UserResponse, AssetResponse]] # 核心:这里告诉 Pydantic,items 里面才是用户列表
@router.get("/all2", response_model=ApiResponse[ListPageResponse], summary="获取商品和用户数据")
async def get_all_users2(request: Request,
prod_data: Annotated[UserListForm, Query()],
db: AsyncSession = Depends(get_db)):
二,测试效果:

浙公网安备 33010602011771号