django ninja通过@paginate装饰器即可进行分页。内置了两个分页管理器LimitOffsetPagination和PageNumberPagination,能够实现基本的分页要求。当内置分页器不满足要求时,可以继承PaginationBase进行扩展自己的分页管理器。
1 使用分页器
from ninja.pagination import paginate@api.get('/users', response=List[UserSchema])
@paginate
def list_users(request):return User.objects.all()
/api/users?limit=10&offset=0
返回:
{
"items": [],
"count": 10
}
2 ninja自带分页器
2.1 LimitOffsetPagination
默认paginate使用的就是该分页器。
2.2 PageNumberPagination
@api.get("/users")
@paginate(PageNumberPagination, page_size=50)
def list_users(...
返回结果包含items和count
{
"items": [],
"count": 10
}
2.3 自定义分页器
这个自定义分页器定义了Input、Output、paginate_queryset。
实现了page和page_size参数获取数据。page_size可以通过多种方式进行调节。在定义接口的时候设置固定值,或者使用分页器的默认值,或者使用用户的传输参数。
返回结果,新增多个字段,修改默认items为data。
#!/usr/bin/env python
# coding=utf-8
# @Time : 2024/2/2 15:40
# @Software: PyCharm
import math
from ninja import Schema
from ninja.pagination import PaginationBase
from typing import List, Any, Optionalclass CustomPagination(PaginationBase):def __init__(self, page_size: Optional[int] = None, **kwargs):""" 如果指定具体值,那么用户参数中的page_size将会失效。page_size: 在定义接口是可以设置的每页记录数。例如:@api.get("/book")@paginate(CustomPagination)def book_list(request):return Book.objects.all()@api.get("/book")@paginate(CustomPagination, page_size=10) # 定义接口默认每页数量def book_list(request):return Book.objects.all()"""self.page_size = page_sizesuper().__init__(**kwargs)class Input(Schema):""" 输入参数,两个参数。1. page(必须2. page_size(可选)"""page: intpage_size: int = 5class Output(Schema):"""输出结果。1. data 数据集合2. total:总记录数3. per_page:每页记录数4. total_page:总页数5. page:当前页"""data: List[Any] # <--- datatotal: intper_page: inttotal_page: intpage: intdef paginate_queryset(self, queryset, pagination: Input, **params):page = pagination.pagepage_size = self.page_size or pagination.page_sizestart_idx = (page - 1) * page_sizeend_idx = start_idx + page_sizetotal_count = queryset.count()return {'data': queryset[start_idx: end_idx], # <--- data'total': total_count,'per_page': page_size,'total_page': math.ceil(total_count / page_size),'page': page}items_attribute: str = "data" # <--- 将默认数据集合的名称从items修改成data