一、内置分页API的使用
rest framework内置了三种API可供使用,分别为PageNumberPagination、LimitOffsetPagination以及CursorPagination,其中CursorPagination为加密分页,并且性能最优,因为它会记住上一次页码的位置,这样反应速度是最快的。
1、PageNumberPagination
- 导入API:
from rest_framework.pagination import PageNumberPagination
- 在settings中配置PAGE_SIZE参数
REST_FRAMEWORK = { "PAGE_SIZE":2, }
- API实例化并且获取分页的queryset
class BookView(GenericViewSet): queryset = models.Book.objects.all() serializer_class = BookModelSerializer def list(self,request): queryset= self.get_queryset() pg = PageNumberPagination() paginate_queryset = pg.paginate_queryset(queryset=queryset,request=request,view=self) bs=self.get_serializer(paginate_queryset,many=True) return Response(bs.data)
- 发送请求获取分页后的数据
在API中默认的请求参数是page所以可以发送类似下面的请求方式,获取每一页的分页数据:
http://127.0.0.1:8020/books/?page=2
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
[ { "id": 1, "title": "语文", "price": 12, "pub_date": "2019-09-09", "publish": 1, "authors": [ 1, 2, 3 ] }, { "id": 2, "title": "数学", "price": 22, "pub_date": "2019-09-17", "publish": 2, "authors": [ 1, 3 ] } ]
- get_paginated_response
这时另一个返回数据结构的API,和Response不太一样:
def get_paginated_response(self, data): return Response(OrderedDict([ ('count', self.page.paginator.count), ('next', self.get_next_link()), ('previous', self.get_previous_link()), ('results', data) ]))
2、LimitOffsetPagination
这种分页样式反映了查找多个数据库记录时使用的语法。客户端包含 “limit” 和 “offset” 查询参数。limit 表示要返回的数据的最大数量,等同于其它样式中的 page_size
。
offset 指定查询的起始位置与完整的未分类 数据集的关系。
from rest_framework.pagination import LimitOffsetPagination class BookView(GenericViewSet): queryset = models.Book.objects.all() serializer_class = BookModelSerializer def list(self,request): queryset= self.get_queryset() lg = LimitOffsetPagination() paginate_queryset = lg.paginate_queryset(queryset=queryset,request=request,view=self) bs=self.get_serializer(paginate_queryset,many=True) return Response(bs.data)
此时访问可以通过以下请求形式获取数据:
http://127.0.0.1:8020/books/?limit=3&offset=2
- 参数
limit:表示每次请求数据的个数,相当于pageSize
offset:表示从第几个数据开始,如果offset=0表示从id=1的数据开始往后取
3、CursorPagination
from rest_framework.pagination import CursorPagination class BookView(GenericViewSet): queryset = models.Book.objects.all() serializer_class = BookModelSerializer def list(self,request): queryset= self.get_queryset() #创建分页对象 cg = CursorPagination() #获取分页数据 paginate_queryset = cg.paginate_queryset(queryset=queryset, request=request, view=self) #序列化分页数据 bs=self.get_serializer(paginate_queryset,many=True) return Response(bs.data)
当然还需要在settings中进行配置:
REST_FRAMEWORK = { "PAGE_SIZE":2, }
二、自定义分页API
from rest_framework.pagination import PageNumberPagination class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_size_query_param = 'size' #每页出现的记录数 max_page_size = 5 page_query_param = 'page' #请求第几页
在视图中可以直接使用这个自定义的分页类:
class BookView(GenericViewSet): queryset = models.Book.objects.all() serializer_class = BookModelSerializer def list(self,request): queryset= self.get_queryset() #创建分页对象 pg = MyPageNumberPagination() #获取分页数据 paginate_queryset = pg.paginate_queryset(queryset=queryset, request=request, view=self) #序列化分页数据 bs=self.get_serializer(paginate_queryset,many=True) return pg.get_paginated_response(bs.data)
请求url类似如下:
http://127.0.0.1:8020/books/?page=1&size=3
其余API的自定义也是类似如此:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from rest_framework.pagination import LimitOffsetPagination class MyLimitOffsetPagination(LimitOffsetPagination): default_limit = 2 limit_query_param = 'limit' offset_query_param = 'offset' max_limit = 5
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from rest_framework.pagination import CursorPagination class MyCursorPagination(CursorPagination): cursor_query_param = 'cursor' page_size = 2 ordering = 'id' page_size_query_param = None max_page_size = None