Fork me on GitHub

rest framework之分页组件

一、内置分页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
[
    {
        "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的自定义也是类似如此:

from rest_framework.pagination import LimitOffsetPagination


class MyLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    max_limit = 5
MyLimitOffsetPagination
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
MyCursorPagination

 

posted @ 2019-09-11 21:11  iveBoy  阅读(387)  评论(0编辑  收藏  举报
TOP