zoukankan      html  css  js  c++  java
  • django: django rest framework 分页

    django: django rest framework 分页

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linux_player_c/article/details/80645969

    django rest framework pagination

    在drf中对于数据的返回支持多种分页技巧,在官网中主要向我们介绍了PageNumberPagination、LimitOffsetPagination、CursorPagination。

    本课程的讲解使用示例项目,该项目的目录结构如下所示: 
    这里写图片描述

    目录结构

    该目录结构与django原生的目录结构差异较大,其中所有的django应用都在apps目录中,目前拥有assets和rbac两个应用。conf内存放的是urls,py和wsgi.py文件,在settings目录中写入了该项目的配置文件base.py。

    对于drf的分页可以采用全局配置和对每个视图进行单独配置的方法。

    如果采用全局配置需要在配置文件中设置,例如将全局分页设置为PageNumberPagination,需要在base.py中添加如下配置:

    REST_FRAMEWORK = {
        'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
        'PAGE_SIZE': 100
    }
    • 1
    • 2
    • 3
    • 4

    如果需要对每个视图进行单独配置,需要设置ModelViewSet中的pagination_class值,示例如下:

    class MachineRoomViewSet(viewsets.ModelViewSet):
        """
        机房操作视图
        """
        queryset = MachineRoom.objects.all()
        serializer_class = MachineRoomSerializer
        pagination_class = PageNumberPagination
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    下面分别介绍这三个的使用方法:


    PageNumberPagination

    此分页样式在请求查询参数中接受单个号码页码。用户可以指定访问的页数,示例如下:

    GET http://127.0.0.1:8060/assets/v1/regions/?page=2
    • 1

    返回的内容如下:

    HTTP 200 OK
    Allow: GET, POST, HEAD, OPTIONS
    Content-Type: application/json
    Vary: Accept
    
    {
        "results": [
            {
                "id": 3,
                "region_name": "华西",
                "created_time": "2018-06-20T08:52:32.871964Z",
                "modified_time": null
            },
            {
                "id": 4,
                "region_name": "华北",
                "created_time": "2018-06-20T14:47:46.910065Z",
                "modified_time": null
            }
        ],
        "pagination": 4,
        "page_size": 2,
        "page": 2
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    按照页数访问是比较常见的一种做法,所以我们大多数情况使用PageNumberPagination,上述的返回结果集进行了调整,这是继承PageNumberPagination类,对其get_paginated_response函数的返回内容格式进行了再定义。 
    后续在介绍自定义分页格式时会进行详细介绍。PageNumberPagination的默认返回格式为:

    HTTP 200 OK
    {
        "count": 1023
        "next": "https://api.example.org/accounts/?page=5",
        "previous": "https://api.example.org/accounts/?page=3",
        "results": [
           …
        ]
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    包含next(下一页)和previous(上一页)两个跳转地址。


    LimitOffsetPagination

    这种分页样式反映了查找多个数据库记录时使用的语法,客户端包含“limit(限制)”和“offset(偏移量)”查询参数。 
    该限制表示要返回的项目的最大数量,并且等同于其他样式中的page_size。 
    偏移量指示查询的起始位置与完整的未分类项目集的关系。

    使用这种分页方式的model进行查询的时候需要指定limit(个数)和offset(起始位置)。

    GET http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=2
    • 1

    返回结果如下:

    HTTP 200 OK
    Allow: GET, POST, HEAD, OPTIONS
    Content-Type: application/json
    Vary: Accept
    
    {
        "count": 4,
        "next": "http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=3",
        "previous": "http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=1",
        "results": [
            {
                "id": 3,
                "region_name": "华西",
                "created_time": "2018-06-20T08:52:32.871964Z",
                "modified_time": null
            }
        ]
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    CursorPagination

    基于游标的分页提供了一个不透明的 “游标” 指示器,客户端可以使用该指示器来翻阅结果集。此分页样式仅提供前向和反向控件,并且不允许客户端导航到任意位置。

    基于游标的分页需要在结果集中存在唯一的,不变的 item 顺序。这种排序通常可以是记录上的创建时间戳,因为这确保了排序的一致性。

    假设我们以创建时间来进行排序,新建时间一般是无法进行修改的。该字段的内容只需要设置一次。但是时间也有可能冲突。为了避免这种重复问题,可以对该条信息的数据抽取出特征值而组合成一个唯一的字符串。例如:假设我们我们对一个云主机设置一个不会冲突的字段:可以使用如下格式“名称-规格-创建时间”,这样的一条信息应该是不会冲突的。

    CursorPagination的参数配置如下:

    page_size = 指定页面大小的数字值。如果设置,则会覆盖 PAGE_SIZE 设置。默认值与 PAGE_SIZE setting key 相同。 
    cursor_query_param = 一个字符串值,指定 “游标” 查询参数的名称。默认为 ‘cursor’. 
    ordering = 这应该是一个字符串或字符串列表,指定将应用基于游标的分页的字段。例如: ordering = ‘slug’。默认为 -created。该值也可以通过在视图上使用 OrderingFilter 来覆盖。 
    template = 在可浏览 API 中渲染分页控件时使用的模板的名称。可能会被覆盖以修改渲染样式,或设置为 None 以完全禁用 HTML 分页控件。默认为 “rest_framework/pagination/previous_and_next.html”


    自定义分页类

    除了drf给出的上述三种分页方法,用户可以根据自己的需求进行自定义分页以适应不同业务需求。这个可以继承并拓展drf的分页类。我们编写一个MyFormatResultsSetPagination自定义分页类,该类继承自PageNumberPagination,内容如下:

    class MyFormatResultsSetPagination(pagination.PageNumberPagination):
    
        page_size_query_param = "page_size"
        page_query_param = 'page'
        page_size = 2
        max_page_size = 1000
    
        """
        自定义分页方法
        """
        def get_paginated_response(self, data):
            """
            设置返回内容格式
            """
            return Response({
                'results': data,
                'pagination': self.page.paginator.count,
                'page_size': self.page.paginator.per_page,
                'page': self.page.start_index() // self.page.paginator.per_page + 1
            })
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在get_paginated_response重写了返回格式。

    如果要使用自定义分页类,只需要在ModelViewSet中设定pagination_class为自定义分类。示例如下:

    class RegionViewSet(viewsets.ModelViewSet):
        """
        区域操作视图
        """
        queryset = Region.objects.all()
        serializer_class = RegionSerializer
        pagination_class = MyFormatResultsSetPagination    # 自定义分页
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    小结

    分页是后端restful接口一个非常常见的需求,django rest framework为我们编写业务简化了很多操作。需要熟练掌握。

  • 相关阅读:
    codeforce A. 2Char(水题,暴力)
    hdu 4704 Sum(组合,费马小定理,快速幂)
    light oj 1100
    hdu 4503 湫湫系列故事——植树节(组合概率)
    Codeforces Round #327 (Div. 1), problem: (A) Median Smoothing
    hdu-3833 YY's new problem(数组标记)
    hdu 4549 M斐波那契数列(快速幂 矩阵快速幂 费马小定理)
    hdu 1431 素数回文(暴力打表,埃托色尼筛法)
    hdu 1430 (BFS 康托展开 或 map )
    hdu 1024 max sum plus plus
  • 原文地址:https://www.cnblogs.com/hanbowen/p/10069544.html
Copyright © 2011-2022 走看看