zoukankan      html  css  js  c++  java
  • Django rest framework 之分页

    Django rest_framework 中分页可分为三类:

    • PageNumberPagination:看第 n 页,每页显示 n 条数据
    • LimitOffsetPagination:在 n 个位置,向后查看 n 条数据
    • CursorPagination:加密分页,只能看上一页和下一页

    一、PageNumberPagination

    在这里将采用 rest_framework 内置的页面渲染器 Response

    1、api/serializers.py

    class PagesSerializers(serializers.ModelSerializer):
        """分页"""
    
        class Meta:
            model = models.Role
            fields = '__all__'
    

    2、api/views.py

    from rest_framework.response import Response    # 渲染器
    from .serializers import PagesSerializers
    
    from app import models
    from rest_framework.pagination import PageNumberPagination
    
    
    class PageView(APIView):
        """分页"""
        def get(self, request, *args, **kwargs):
            """示例:
            http://api.example.org/accounts/?page=4
            http://api.example.org/accounts/?page=4&page_size=100
            """
            roles = models.Role.objects.all()
            # 创建分页对象
            pg = PageNumberPagination()
            # 获取分页数据
            page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
            # 将分页后的数据序列化
            roles_ser = PagesSerializers(instance=page_roles, many=True)
    
            # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response
            return Response(roles_ser.data)
    

    3、api/urls.py

    from django.urls import path, re_path
    from api.views import UserView, ParserView, RolesView, UserInfoView, GroupView, UserGroupView, PageView
    
    urlpatterns = [
    
        re_path('(?P<version>[v1|v2]+)/pages/', PageView.as_view()),    # 分页
    
    ]
    

    4、另外需要配置每页显示的条数 settings.py

    REST_FRAMEWORK = {
        "DEFAULT_VERSION": 'v1',               # 默认的版本
        "ALLOWED_VERSIONS": ['v1', 'v2'],       # 允许的版本
        "VERSION_PARAM": 'version',             # GET方式url中参数的名字  ?version=xxx
        "PAGE_SIZE": 2,     # 每页最多显示两条数据
    }
    

    5、访问(第二页数据):http://127.0.0.1:8000/api/v2/pages/?page=2

    自定义分页

    定义一个类,让它继承 PageNumberPagination

    1、api/views.py

    class MyPageNumberPagination(PageNumberPagination):
        """自定义分页类"""
        page_size = 2       # 每页最多显示的条数
        page_query_param = 'page'   # 查询参数,URL 中的过滤参数
    
        # 通过 page_size 每页只显示 2 条,使用下面这个参数可以改变默认显示条数
        # 使用方法 http://127.0.0.1:8000/api/v2/pages/?page=2&size=3
        page_size_query_param = 'size'
        max_page_size = 10   # 最大页数
    
    
    class PageView(APIView):
        """分页"""
        def get(self, request, *args, **kwargs):
            """
            http://api.example.org/accounts/?page=4
            http://api.example.org/accounts/?page=4&page_size=100
            """
            roles = models.Role.objects.all()
            # 创建分页对象
            # pg = PageNumberPagination()
            pg = MyPageNumberPagination()
            # 获取分页数据
            page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
            # 将分页后的数据序列化
            roles_ser = PagesSerializers(instance=page_roles, many=True)
    
            # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response
            return Response(roles_ser.data)
    

    2、访问:http://127.0.0.1:8000/api/v2/pages/?page=2&size=1

    二、LimitOffsetPagination

    LimitOffsetPagination 可以控制只查看多少条,以及偏移量 offset 后多少条数据,格式为:

    http://api.example.org/accounts/?limit=100      # 控制查看 100 条数据
    http://api.example.org/accounts/?offset=400&limit=100   # 偏移量 400,查看条数 100,即查看 400 后的 100 条数据
    

    使用方法与 PageNumberPagination 一致:

    from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination
    
    class PageView(APIView):
        """分页"""
        def get(self, request, *args, **kwargs):
            """
            http://api.example.org/accounts/?page=4
            http://api.example.org/accounts/?page=4&page_size=100
            """
            roles = models.Role.objects.all()
            # 创建分页对象
            # pg = PageNumberPagination()
            # pg = MyPageNumberPagination()
            pg = LimitOffsetPagination()
            # 获取分页数据
            page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
            # 将分页后的数据序列化
            roles_ser = PagesSerializers(instance=page_roles, many=True)
    
            # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response
            return Response(roles_ser.data)
    

    查看第 2 条数据后的 3 条数据:

    自定义

    同样地 LimitOffsetPagination 也支持自定义:

    #自定义分页类2
    class MyLimitOffsetPagination(LimitOffsetPagination):
        #默认显示的个数
        default_limit = 2
        #当前的位置
        offset_query_param = "offset"
        #通过limit改变默认显示的个数
        limit_query_param = "limit"
        #一页最多显示的个数
        max_limit = 10
    

    get_paginated_response() 方法控制前后页面

    api/views.py

    class PageView(APIView):
        """分页"""
        def get(self, request, *args, **kwargs):
            """
            http://api.example.org/accounts/?page=4
            http://api.example.org/accounts/?page=4&page_size=100
            """
            roles = models.Role.objects.all()
            # 创建分页对象
            # pg = PageNumberPagination()
            # pg = MyPageNumberPagination()
            pg = LimitOffsetPagination()
            # 获取分页数据
            page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
            # 将分页后的数据序列化
            roles_ser = PagesSerializers(instance=page_roles, many=True)
    
            # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response
            # return Response(roles_ser.data)
            return pg.get_paginated_response(roles_ser.data)        # 这一行
    

    效果如下:

    三、CursorPagination

    CursorPagination 将页码进行加密,使得不能通过 URL 来控制显示的页面

    1、这里使用自定义分页类 api/views.py

    class MyCursorPagination(CursorPagination):
        """自定义分页类"""
        page_size = 2       # 每页最多显示的条数
        cursor_query_param = 'cursor'   # 查询参数,URL 中的过滤参数
    
        ordering = 'id'       # 通过什么排序(正序)
        page_size_query_param = None
        max_page_size = None  # 最大页数
    
    
    class PageView(APIView):
        """分页"""
        def get(self, request, *args, **kwargs):
            """
            http://api.example.org/accounts/?page=4
            http://api.example.org/accounts/?page=4&page_size=100
            """
            roles = models.Role.objects.all()
            # 创建分页对象
            # pg = PageNumberPagination()
            # pg = MyPageNumberPagination()
            # pg = LimitOffsetPagination()
            pg = MyCursorPagination()
            # 获取分页数据
            page_roles = pg.paginate_queryset(queryset=roles, request=request, view=self)
            # 将分页后的数据序列化
            roles_ser = PagesSerializers(instance=page_roles, many=True)
    
            # 将序列化后的数据渲染到前端显示,这里采用的是 rest_framework 的渲染器 Response
            # return Response(roles_ser.data)
            return pg.get_paginated_response(roles_ser.data)
    

    2、访问: http://127.0.0.1:8000/api/v2/pages/

  • 相关阅读:
    React Native入门教程2 -- 基本组件使用及样式
    React Native入门教程 1 -- 开发环境搭建
    [轻松一下] 大热天的宿舍太热了,来网吧敲代码
    读外部存储的权限READ_EXTERNAL_STORAGE
    【翻译】Ext JS 6.2 早期访问版本发布
    等火车
    HTTP 简介
    建造模式Builder
    DP解LCS问题模板及其优化(模板)
    poj1015 正解--二维DP(完全背包)
  • 原文地址:https://www.cnblogs.com/midworld/p/11380154.html
Copyright © 2011-2022 走看看