wance_data/src/utils/paginations.py

75 lines
2.0 KiB
Python
Raw Normal View History

2024-10-08 06:06:24 +00:00
from typing import Generic, Optional, Sequence, TypeVar
import math
from fastapi import Query
from pydantic import BaseModel
from tortoise.queryset import QuerySet
T = TypeVar("T")
class PaginationPydantic(BaseModel, Generic[T]):
"""分页模型"""
status_code: int = 200
message: str = "Success"
total: int
page: int
size: int
total_pages: int
data: Sequence[T]
class Params(BaseModel):
"""传参"""
# 设置默认值为1不能够小于1
page: int = Query(1, ge=1, description="Page number")
# 设置默认值为10最大为100
size: int = Query(10, gt=0, le=200, description="Page size")
# 默认值None表示选传
order_by: Optional[str] = Query(None, max_length=32, description="Sort key")
async def pagination(pydantic_model, query_set: QuerySet, params: Params, callback=None):
"""分页响应"""
"""
pydantic_model: Pydantic model
query_set: QuerySet
params: Params
callback: if you want to do something for query_set,it will be useful.
"""
page: int = params.page
size: int = params.size
order_by: str = params.order_by
total = await query_set.count()
# 通过总数和每页数量计算出总页数
total_pages = math.ceil(total / size)
if page > total_pages and total: # 排除查询集为空时报错即total=0时
raise ValueError("页数输入有误")
# 排序后分页
if order_by:
order_by = order_by.split(',')
query_set = query_set.order_by(*order_by)
# 分页
query_set = query_set.offset((page - 1) * size) # 页数 * 页面大小=偏移量
query_set = query_set.limit(size)
if callback:
"""对查询集操作"""
query_set = await callback(query_set)
# query_set = await query_set
data = await pydantic_model.from_queryset(query_set)
return PaginationPydantic(**{
"total": total,
"page": page,
"size": size,
"total_pages": total_pages,
"data": data,
})