• 【DRF分页】


    我们数据库有几千万条数据,这些数据需要展示,我们不可能直接从数据库把数据全部读取出来.
    因为这样会给内存造成巨大的压力,很容易就会内存溢出,所以我们希望一点一点的取.

    同样,展示的时候也是一样的,我们必定会对数据进行分页显示.

    本文将详细讲述DRF为我们提供的三种分页方式.

    全局配置

    REST_FRAMEWORK = {
        # 对所有分页器生效,但优先级低
        'PAGE_SIZE': 5,  # 每页显示5条数据
    }
    

    @


    我们先准备好用于测试分页的数据以及序列化类
    .
    数据表

    from django.db import models
    
    class Test(models.Model):
        """用于测试分页的数据表"""
        name = models.CharField(max_length=64)
    

    生成表记录:

    # 在Python脚本中调用Django环境
    import os
    
    if __name__ == '__main__':
        # 将下面的'blog095.settings'改为项目对应的名称后直接执行即可生成记录
        os.environ.setdefault('DJANGO_SETTINGS_MODULE', > 'blog095.settings')
        import django
        django.setup()
        from blog.models import Test  # 导入数据表
        [Test.objects.create(name="花千骨%s" % str(i)) for i in range(100)]
    

    如果不理解此操作,可见文献【在Python脚本中调用Django环境】
    ·
    序列化类

    from rest_framework.serializers import ModelSerializer
    from blog.models import Test  # 导入数据表
    
    class TestSerializer(ModelSerializer):
        """用于测试分页的序列化类"""
        class Meta:
            model = Test
            fields = '__all__'
    

    第一种 PageNumberPagination 查第n页,每页显示n条数据

    第一步 分页器配置文件

    from rest_framework import pagination
    
    class PageNumberPagination(pagination.PageNumberPagination):
        """查第n页,每页显示n条数据"""
        page_size = 10  # 指定每页显示多少条数据
        page_size_query_param = 'size'  # URL参数中每页显示条数的参数
        page_query_param = 'page'  # URL中页码的参数
        max_page_size = None  # 每页最多显示多少条数据
    

    第二步 视图文件

    from rest_framework.response import Response
    from rest_framework.views import APIView
    from rest_framework.serializers import ModelSerializer
    from blog.models import Test  # 导入数据表
    from blog import pagination  # 导入上面的分页配置
    
    class Test01View(APIView):
        def get(self, request):
            queryset = Test.objects.all()
    
            # 1. 实例化分页器对象
            page_obj = pagination.PageNumberPagination()
    
            # 2. 使用自己配置的分页器调用分页方法进行分页
            page_data = page_obj.paginate_queryset(queryset, request)
    
            # 3. 序列化我们分页好的数据
            ser_obj = TestSerializer(page_data, many=True)
    
            # # 4. 返回数据
            # return Response(ser_obj.data)
    
            # 4. 返回带上一页/下一页连接的页面
            return page_obj.get_paginated_response(ser_obj.data)
    

    第三步 访问测试
    在这里插入图片描述
    如上图,指定page=10&size=5后,返回了相应的数据.


    第二种 LimitOffsetPagination 在第n个位置,向后查n条数据

    第一步 分页器配置文件

    from rest_framework import pagination
    
    class LimitOffsetPagination(pagination.LimitOffsetPagination):
        """在第n个位置,向后查n条数据"""
        default_limit = 1  # 指定默认查多少条数据
        limit_query_param = 'limit'  # URL中指定查多少条数据的参数
        offset_query_param = 'offset'  # URL中指定从第几条数据开始查的参数
        max_limit = 999  # 最大显示多少条数据
    

    第二步 视图文件

    from rest_framework.response import Response
    from rest_framework.views import APIView
    from rest_framework.serializers import ModelSerializer
    from blog.models import Test  # 导入数据表
    from blog.pagination import LimitOffsetPagination  # 导入上面的分页配置
    
    
    class Test02View(APIView):
        def get(self, request):
            queryset = Test.objects.all()
    
            # 1. 实例化分页器对象
            page_obj = LimitOffsetPagination()
    
            # 2. 使用自己配置的分页器调用分页方法进行分页
            page_data = page_obj.paginate_queryset(queryset, request)
    
            # 3. 序列化我们分页好的数据
            ser_obj = TestSerializer(page_data, many=True)
    
            # # 4. 返回数据
            # return Response(ser_obj.data)
    
            # 4. 返回带上一页/下一页连接的页面
            return page_obj.get_paginated_response(ser_obj.data)
    

    第三步 访问测试在这里插入图片描述


    第三种 CursorPagination 加密游标的分页

    第一步 分页器配置文件

    from rest_framework import pagination
    
    class CursorPagination(pagination.CursorPagination):
        """加密游标的分页"""
        cursor_query_param = 'cursor'  # 游标(这是加密的游标)
        # ordering = '-id'  # 从后往前取数据
        ordering = 'id'
        page_size = 1  # 每页显示的条数
    

    第二步 视图文件

    from rest_framework.response import Response
    from rest_framework.views import APIView
    from rest_framework.serializers import ModelSerializer
    from blog.models import Test  # 导入数据表
    from blog.pagination import CursorPagination  # 导入上面的分页配置
    
    class Test03View(APIView):
        def get(self, request):
            queryset = Test.objects.all()
    
            # 1. 实例化分页器对象
            page_obj = CursorPagination()
    
            # 2. 使用自己配置的分页器调用分页方法进行分页
            page_data = page_obj.paginate_queryset(queryset, request)
    
            # 3. 序列化我们分页好的数据
            ser_obj = TestSerializer(page_data, many=True)
    
            # # 4. 返回数据
            # return Response(ser_obj.data)
    
            # 4. 返回带上一页/下一页连接的页面
            return page_obj.get_paginated_response(ser_obj.data)
    

    好了,打开浏览器去测试吧.

    还可以使用DRF视图系统生成带有上一页/下一页按钮的页面.

    from rest_framework.viewsets import ModelViewSet
    
    class Test04View(ModelViewSet):
        queryset = Test.objects.all()
        serializer_class = TestSerializer
        pagination_class = CursorPagination  # 指定分页配置器
    

    如下图:
    在这里插入图片描述
    is ok.



  • 相关阅读:
    [luogu P2184] 贪婪大陆 [树状数组][线段树]
    luogu P3373 【模板】线段树 2
    [luogu P3384] 【模板】树链剖分 [树链剖分]
    树链剖分膜版
    AtCoder Grand Contest 026F
    AtCoder Regular Contest 091F
    AtCoder Regular Contest 099F
    AtCoder Grand Contest 027D
    向量叉积分配律简单证明
    LOJ 538. 「LibreOJ NOIP Round #1」数列递推(找规律+结论)
  • 原文地址:https://www.cnblogs.com/zyk01/p/10176384.html
Copyright © 2020-2023  润新知