drf中分页组件
分页 在查看数据列表的API中,如果数据量比较大,肯定不能把所有的数据都展示给用户,而需要通过分页展示。 在drf中为我们提供了一些分页相关类:
BasePagination 基类 PageNumberPagination(BasePagination) 支持/api/blog/?page=1&size=6 格式的分页 LimitoffsetPagination(BasePagination) 支持 ?offset=10&limit=15 格式的分页
PageNumberPagination
适用于显示页面、上一下、下一页,url格式如下:
/accounts/?page=1 # 第1页 /accounts/?page=2 # 第2页 /accounts/?page=3 # 第3页 /accounts/?page=4 # 第4页 /accounts/?page=5 # 第5页 /accounts/?page=6&page_size=1 #第6页,page_size参数指定每页显示多条数据,不传时会使用默认配置,在settings.py中PAGE_SIZE常量定义默认值; /accounts/?page=7&page_size=2 /accounts/?page=8&page_size=4
使用步骤
1、创建分页对象
2、调用分页对象中某个方法,传入相关参数
3、调用分页对象中某个方法,返回序列化结果
实例:
settings.py
REST_FRAMEWORK = { "PAGE_SIZE":3, # 每页显示多条数据全局配置 }
views.py
from rest_framework.pagination import PageNumberPagination class BlogView(APIView): def get(self, request): # 1、获取博客表中数据 queryset = models.Blog.objects.all().order_by("-id") # 2、创建分页对象 pager = PageNumberPagination() # 调用paginate_queryset()方法 paginate_queryset = pager.paginate_queryset(queryset, request, self) # 3、序列化 ser = BlogModelSerializer(instance=paginate_queryset, many=True) # 4、获取序列化结果 response = pager.get_paginated_response(ser.data) return response
http://127.0.0.1:8001/api/blog/?page=1
默认不支持,动态指定每页数据的数量(page_size参数无效)
例如:http://127.0.0.1:8001/api/blog/?page=1&page_size=6 每页都是返回3条数据是根据PAGE_SIZE值返回。
PageNumberPagination扩展
分页组件默认不支持每页动态返回数据,通过重写分页类属性来实现动态返回每页数据。
views.py
from rest_framework.pagination import PageNumberPagination # 重写PageNumberPagination类属性 class MyPageNumberPagination(PageNumberPagination): page_size_query_param = "size" # 每页显示多少条的参数名 page_size = 2 # 默认一页显示多少条(局部优先使用),分页类属性和settings(PAGE_SIZE)都设置时,使用类属性定义的值。 max_page_size = 8 # 一页最多显示多少条,通过page_size参数动态调整,动态值不能超过这里的设定值 。默认max_page_size=None 不支持动态调整大小, class BlogView(APIView): """博客列表/PageNumberPagination翻页""" authentication_classes = [BlogAuthenticate] def get(self, request): # 1、获取博客表中数据 queryset = models.Blog.objects.all().order_by("-id") # 2、创建分页对象 pager = MyPageNumberPagination() # 调用paginate_queryset()方法 paginate_queryset = pager.paginate_queryset(queryset, request, self) # 3、序列化 ser = BlogModelSerializer(instance=paginate_queryset, many=True) # 4、获取序列化结果 response = pager.get_paginated_response(ser.data) return response
http://127.0.0.1:8001/api/blog/?page=1 # 1页显示2条数据
http://127.0.0.1:8001/api/blog/?page=2&size=5 size参数动态指定每页显示多少条数据
每页显示动态指定参数值不能大于max_page_size值(若传参大于该值,只会返回max_page_szie设定值的数据):
例如:http://127.0.0.1:8001/api/blog/?page=1&size=9 只返回8条数据;
LimitOffsetPagination(滚动翻页)
http://127.0.0.1:8001/api/blog/limit/ 默认显示settings.py中PAGE_SIZE=3 http://127.0.0.1:8001/api/blog/limit/?offset=0 从第0个位置,往后取2条数据,offset指数据在数据库中位置 http://127.0.0.1:8001/api/blog/limit/?offset=1 从第1个位置,往后取2条数据 http://127.0.0.1:8001/api/blog/limit/?offset=1&limit=3 从第1个位置,往后取3条数据 http://127.0.0.1:8001/api/blog/limit/?max_id=5 id小于23的3条数据
实例:
settings.py
REST_FRAMEWORK = { "PAGE_SIZE":3, # 每页显示多条数据全局配置 }
views.py
from rest_framework.pagination import LimitOffsetPagination class BlogLimitView(APIView): """Limit翻页组件""" authentication_classes = [BlogAuthenticate] def get(self, request): # 1、读取数据库中的博客信息 queryset = models.Blog.objects.all().order_by("id") # ?max_id=1 # ?min_id =13 取最新的数据 queryset.filter(id__gt=min_id) max_id = request.query_params.get("max_id") if max_id: queryset = queryset.filter(id__lt=max_id) # 原id基础上往后取 pager = LimitOffsetPagination() paginate_queryset = pager.paginate_queryset(queryset, request, self) ser = BlogModelSerializer(instance=paginate_queryset, many=True) response = pager.get_paginated_response(ser.data) return response
http://127.0.0.1:8001/api/blog/limit/ 从0位置向后获取3条数据
http://127.0.0.1:8001/api/blog/limit/?offset=1
http://127.0.0.1:8001/api/blog/limit/?offset=1&limit=9 id=1向后取9条数据
http://127.0.0.1:8001/api/blog/limit/?max_id=5 id小于5的取3条数据
http://127.0.0.1:8001/api/blog/limit/?max_id=5&offset=3&limit=3