fastapi: docs返回数据同一个节点下有多种model时,直接指定数据类型

一,代码


# 输出给前端的用户信息(安全公开,不含密码,包含只读字段)
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]):
    user_total: int
    user_items: List[UserResponse] # 核心:这里告诉 Pydantic,items 里面才是用户列表
    asset_total: int
    asset_items: List[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)):
    # 参数
    page = prod_data.page
    page_size = prod_data.page_size

    # 使用 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()


    # 数据
    data = {
            "user_items": items,
            "user_total": total,
            "asset_items": asset_items,
            "asset_total": 3,
            }
    # return ApiResponse.fail(code=403,message="测试报错")
    return ApiResponse.success(data=data)

 

二,测试结果:

数据返回:

image

文档:

image

 

posted @ 2026-07-24 23:08  刘宏缔的架构森林  阅读(2)  评论(0)    收藏  举报