• Django Rest framework 之 分页


    一、实例

    分页有三种方式

    • 普通分页,看第n页,每页显示m条数据;
    • 切割分页,在n个位置,向后查看m条数据;
    • 加密分页,这与普通分页方式相似,不过对url中的请求页码进行加密。

    1、路由

    <1>、主路由

    from django.urls import include
    from django.conf.urls import url
    
    urlpatterns = [
        url(r'^api/', include('api.urls', namespace='api') ),
    ]
    
    

    <2>、app路由

    from django.urls import include
    from django.conf.urls import url
    
    urlpatterns = [
        url(r'^page/$', PageView.as_view()),
    ]
    

    2、视图

    在不使用django rest framework中的分页组件仍能够达到目的

    from rest_framework import serializers
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    class PagerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Role
            fields = "__all__"
    
    
    class PageView(APIView):
        def get(self, request , *args, **kwargs):
            roles = Role.objects.get_queryset().order_by('id')
            roles_ser = PagerSerializer(instance=roles, many=True)
    
            return Response(roles_ser.data)  # 只返回数据
    
    

    返回结果

    二、使用普通分页

    1、自定义分页类

    from rest_framework.pagination import PageNumberPagination
    
    class MyPageNumberPagination(PageNumberPagination):
        page_size = 2
        max_page_size = 5
        page_size_query_param = 'size'
        page_query_param = 'page'
    
    • page_query_param:表示url中的页码参数
    • page_size_query_param:表示url中每页数量参数
    • page_size:表示每页的默认显示数量
    • max_page_size:表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃

    2、视图

    class PagerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Role
            fields = "__all__"
    
    class PageView(APIView):
        def get(self, request , *args, **kwargs):
            roles = Role.objects.get_queryset().order_by('id')
            page = MyPageNumberPagination()
            page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
            roles_ser = PagerSerializer(instance=page_roles, many=True)
    
            # return Response(roles_ser.data)  # 只返回数据
            return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
    
    • 首先需要实例化我们定义的分页类
    • 并且对实例化类进行传参控制
    • 最后将分页后的对象作序列化

    3、测试结果

    <1>、正常测试

    http://127.0.0.1:8000/api/page/

    <2>、page、size测试

    http://127.0.0.1:8000/api/page/?page=2&size=3 表示第二页,每页显示三条数据

    三、使用普通分页

    1、自定义分页类

    from rest_framework.pagination import LimitOffsetPagination
    
    class MyLimitOffsetPagination(LimitOffsetPagination):
        default_limit = 2
        limit_query_param = 'limit'
        offset_query_param = 'offset'
        max_limit = 5
    
    • default_limit:表示默认每页显示几条数据
    • limit_query_param:表示url中本页需要显示数量参数
    • offset_query_param:表示从数据库中的第几条数据开始显示参数
    • max_limit:表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃

    2、视图

    class PagerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Role
            fields = "__all__"
    
    class PageView(APIView):
        def get(self, request , *args, **kwargs):
            roles = Role.objects.get_queryset().order_by('id')
            page = MyLimitOffsetPagination()
            page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
            roles_ser = PagerSerializer(instance=page_roles, many=True)
    
            # return Response(roles_ser.data)  # 只返回数据
            return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
    
    • 首先需要实例化我们定义的分页类
    • 并且对实例化类进行传参控制
    • 最后将分页后的对象作序列化

    3、测试结果

    <1>、测试结果一

    http://127.0.0.1:8000/api/page/?

    <2>、测试结果二

    http://127.0.0.1:8000/api/page/?offset=2&limit=3表示从数据库中的第二条数据开始查询三条数据

    四、使用加密分页

    使用加密分页的原因:如果使用普通分页时,由于向用户提供了可选参数page,用户可以直接跳到数据分页之后的任意页码。但是这样做的后果就是,数据库的负载变大,返回结果的效率缓慢。但是一旦使用加密之后,虽然提供可选参数cursor,但是对页码进行加密,用户无法知道当前页,而是以上一页下一页的方式翻阅数据。有效避免了数据库的负荷。但是就需要向用户提供上一页下一页的url

    1、自定义分页类

    from rest_framework.pagination import LimitOffsetPagination
    
    class MyCursorPagination(CursorPagination):
    
        cursor_query_param = 'cursor'
        page_size = 2  
        ordering = 'id'
        page_size_query_param = 'size' 
        max_page_size = 5  
    
    • default_limit:表示默认每页显示几条数据
    • cursor_query_param:表示url中页码的参数
    • page_size_query_param:表示每页显示数据量的参数
    • max_page_size:表示每页最大显示数量,做限制使用,避免突然大量的查询数据,数据库崩溃
    • ordering:表示返回数据的排序方式

    2、视图

    class PagerSerializer(serializers.ModelSerializer):
        class Meta:
            model = Role
            fields = "__all__"
    
    class PageView(APIView):
        def get(self, request , *args, **kwargs):
            roles = Role.objects.get_queryset().order_by('id')
            page = MyCursorPagination()
            page_roles = page.paginate_queryset(queryset=roles, request=request, view=self)
            roles_ser = PagerSerializer(instance=page_roles, many=True)
    
            return page.get_paginated_response(roles_ser.data)  # 返回前后夜url
    
    • 首先需要实例化我们定义的分页类
    • 并且对实例化类进行传参控制
    • 最后将分页后的对象作序列化
    • 由于要想用户提供可用的上下页接口,所以只能用return page.get_paginated_response(roles_ser.data)做返回

    3、测试结果

    <1>、测试结果一

    http://127.0.0.1:8000/api/page/?

    <2>、测试结果二

    http://127.0.0.1:8000/api/page/?cursor=cD0z&size=3这里直接点击下一页url并追加每页显示数据量参数size

    五、总结

    三种分页中,普通分页与django中的分页基本没有区别。不过要做分页返回给前端数据,就要从数据库中取出数据,然后在做分页序列化。如果用户一下在前几页请求数据库中的最后几页数据,对查询数据库的时延,对数据库的负载较大,就会出现问题,这个时候就可以使用加密分页,限制用户的访问,只提供前一页和后一页的接口。

  • 相关阅读:
    iOS仿UC浏览器顶部频道滚动效果
    OC中NSClassFromString()与NSStringFromClass()的用法及应用场景
    利用工具MailUtils实现邮件的发送,遇到的大坑,高能预警!!
    使用response实现文件下载注意点
    mac版MyEclipse的安装及创建web项目
    Mac系统下安装Tomcat,以及终端出现No such file or directory的错误提示解决方案
    机器学习笔记-Python简介
    解决mscordacwks.dll不一致问题
    IIS日志如何记录X-Forwarded-For
    深入理解Redis(番外)——持久化
  • 原文地址:https://www.cnblogs.com/welan/p/9952801.html
Copyright © 2020-2023  润新知