分页问题,主要有3类:
a. 根据页码进行分页
b. 位置和个数进行分页
c. 游标分页
1.根据页码进行分页 (http://127.0.0.1:8000/test/?page=2)
urls.py
1 url(r'test/', views.TestView.as_view(), name='test'),# 根据页码进行分页
views.py
from rest_framework.views import APIView from rest_framework import serializers from app01 import models from rest_framework.pagination import PageNumberPagination class StandarResultSetPagination(PageNumberPagination): page_size = 2 # 默认每页显示的数据条数 page_size_query_param = 'page_size' # # 获取URL参数中设置的每页显示数据条数 page_query_param = 'page' # 获取url中参数传入的页码key max_page_size = 2 # 最大支持的每页显示的数据条数 class UserSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = "__all__" class TestView(APIView): def get(self,request,*args,**kwargs): user_list = models.User.objects.all().order_by('-id') paginator = StandarResultSetPagination() # 实例化分页对象 # 获取数据库中的分页数据 page_user_list = paginator.paginate_queryset(user_list,self.request,view=self) print(page_user_list) # 也就是当前页的querySet列表 ser = UserSerializer(instance=page_user_list,many=True) # # 生成分页和数据 response = paginator.get_paginated_response(ser.data) print('下一页url:',paginator.get_next_link()) print('上一页url:',paginator.get_previous_link()) # print(paginator.get_html_context()) # 一个字典,里边的有个key是page_links,值是一个列表,是全部的页面链接 # print(paginator.to_html()) # 生成一个html,页码部分 print(response.data['results']) # 当前页的数据 return response def post(self, request, *args, **kwargs): return Response('post 分页返回的数据')
2.位置和个数进行分页(http://127.0.0.1:8000/test/?limit=2&offset=2)
urls.py
url(r'test/', views.TestView.as_view(), name='test'),# 位置和个数进行分页
views.py
# 例如:我们可以拿到当前页的最后一条数据的ID,在偏移20,就拿到了距离当前页最后一条数据20条后的数据做开始的数据,再配合limit来显示) from rest_framework.pagination import LimitOffsetPagination class UserSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = "__all__" class StandarResultSetPagination(LimitOffsetPagination): default_limit = 2 # 默认每页显示的数据条数,如果default_limit大于max_limit,则按照max_limit的值来显示 limit_query_param = 'limit' # url中传入的显示数据条数的参数 offset_query_param = 'offset' # URL中传入的数据位置的参数,这个偏移量,是与最开始的位置开始偏移,相当于id=0,偏移50条,那就是51条开始,取2条数据 max_limit = 3 class TestView(APIView): # url应该是这样子:http://127.0.0.1:8000/test/?limit=4&offset=3 # 从数据的起始位置,偏移3条,开始取4条,显示在当前页 def get(self,request,*args,**kwargs): user_list= models.User.objects.all().order_by('-id') paginator = StandarResultSetPagination() # 获取分页的queytSet数据 page_user_list = paginator.paginate_queryset(user_list,self.request,view=self) print(page_user_list) ser = UserSerializer(page_user_list,many=True) response = paginator.get_paginated_response(ser.data) print(paginator.get_limit(request) == page_user_list) print(paginator.get_html_context()) print(paginator.to_html()) return response
3.游标分页 (例如我们只提供上一页,下一页,客户只能点击,页码参数也加密了)
urls.py
url(r'test/', pagination.TestView.as_view(), name='test'),# 游标分页
views.py
# 3.游标分页(相当于我只提供上一页,下一页,用户只能点击) from rest_framework.pagination import CursorPagination class StandarResultSetPaginator(CursorPagination): cursor_query_param = 'cursor' # url传入的游标参数 page_size = 2 # 每页显示几条数据 page_size_query_param = 'page_size' max_page_size = 3 # 每页显示的最大条数 ordering = 'id' # 根据ID从大到小排列 class UserSerializer(serializers.ModelSerializer): class Meta: model = models.User fields = "__all__" class TestView(APIView): def get(self,request,*args,**kwargs): user_list = models.User.objects.all().order_by('-id').first() paginator = StandarResultSetPaginator() paginator_list = paginator.paginate_queryset(user_list,self.request,view=self) ser = UserSerializer(paginator_list,many=True) response = paginator.get_paginated_response(ser.data) print(paginator.encode_cursor(paginator.decode_cursor(request))) # print(paginator.base_url) return response