yyz notes yyz notes
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

益章

可乐鸡翅
首页
  • RBAC权限设计
  • 架构图标设计
  • 账号体系
  • python基础
  • python高级
  • python模块
  • python设计模式
  • python数据结构与算法
  • django
  • django-DRF
  • flask
  • 直接设计开源pip包
  • 直接设计开源项目
  • python示例题/脚本
  • python面试题
  • golang基础
  • golang高级
  • golang常用组件
  • gin框架
  • es6
  • javascript
  • react
  • vue
  • TypeScript
  • mysql
  • redis
  • minio
  • elasticsearch
  • mongodb
  • 消息队列
  • 自动化测试
  • 操作系统

    • linux
    • windows
  • nginx
  • docker
  • k8s
  • git
  • ldap
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • python基础

  • python高级

  • python模块

  • python设计模式

  • python数据结构与算法

  • django

  • django-DRF

    • win环境快速搭建drf项目
    • DRF介绍及快速使用
    • 序列化
    • DRF请求和响应
    • DRF类视图
    • 认证
    • 权限
    • 接口访问控制(限流)
    • 版本
    • 分页
      • 1. 分页介绍
      • 2 全局分页
      • 3. 局部分页
      • 4. 可选分页器(自定义分页)
        • PageNumberPagination
        • LimitOffsetPagination
        • CursorPagination(加密分页)
        • 自定义示例
    • 解析器
    • 自定义异常格式
    • 自定义响应格式
    • 过滤
    • 搜索
    • 排序
  • flask

  • 自己设计开源pip包

  • 自己设计开源项目

  • python小示例

  • python面试题

  • python
  • django-DRF
YiZhang-You
2023-05-20
目录

分页

# 1. 分页介绍

当对于数据量的大的时候,我们在一个页面显示不下,这个时候我们就需要采用分页的操作。

分页方式:

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

# 2 全局分页

我们可以在配置文件中设置全局的分页方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每页数目
}
1
2
3
4

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None
1

# 3. 局部分页

# ***************** 分页 ********************
from rest_framework.response import Response
from rest_framework.pagination import PageNumberPagination

from . import models

class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'

class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all()
        pg = PageNumberPagination()
        data = pg.paginate_queryset(queryset=roles,request=request,view=self)
        pg_data = PageSerializer(instance=data, many=True)
        return Response(pg_data.data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
url(r'^(?P<version>[v1|v2]+)/page1/$', views.PageGroupView.as_view()),  # 分页
1

# 4. 可选分页器(自定义分页)

# PageNumberPagination

可以在子类中定义的属性:

  • page_size 每页数目
  • page_query_param 前端发送的页数关键字名,默认为"page"
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量

分页,看第n页,每页显示n条数据;

class MyPageNumberPagination(PageNumberPagination):
    """
    http://127.0.0.1:8000/api/v1/page1/?page=2
    """
    page_size = 2
    page_size_query_param = 'page_size'  # http://127.0.0.1:8000/api/v1/page1/?page=1&page_size=6 重新指定每页显示的条数
    max_page_size = 5

class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'

class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        pg = MyPageNumberPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles,request=request,view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        return Response(pg_data.data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# LimitOffsetPagination

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直
  • limit_query_param limit参数名,默认'limit'
  • offset_query_param offset参数名,默认'offset'
  • max_limit 最大limit限制,默认None

分页,在n个位置,向后查看n条数据;

class MyLimitOffsetPagination(LimitOffsetPagination):
    """
    http://127.0.0.1:8000/api/v1/page1/?offset=3&limit=4  # 第三页显示4条数据
    """
    default_limit = 2  # 默认为每页2条
    limit_query_param = 'limit'  # 第几页
    offset_query_param = 'offset'  # 显示几条数据
    max_limit = 5  # 最大每页5条

class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'

class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        # pg = MyPageNumberPagination()
        pg = MyLimitOffsetPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles, request=request, view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        # return Response(pg_data.data)
        return pg.get_paginated_response(pg_data.data)  # 添加一些参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# CursorPagination(加密分页)

加密分页,上一页和下一页

class MyCursorPagination(CursorPagination):
    """
    加密分页
    "next": "http://127.0.0.1:8000/api/v1/page1/?cursor=cD00",
    "previous": "http://127.0.0.1:8000/api/v1/page1/?cursor=cj0xJnA9Mw%3D%3D",
    """
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 2  # 每页二条
    ordering = 'id'  # 以id查询  -id:表示逆序
    page_size_query_param = None  # 名称 
    max_page_size = None  # 最大条数

class PageSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Role
        fields = '__all__'

class PageGroupView(APIView):
    def get(self, request, *args, **kwargs):
        # 获取使用数据
        roles = models.Role.objects.all()
        # 创建分页对象
        # pg = MyPageNumberPagination()
        # pg = MyLimitOffsetPagination()
        pg = MyCursorPagination()
        # 在数据库中获取分页的数据
        data = pg.paginate_queryset(queryset=roles, request=request, view=self)
        # 对数据进行序列化
        pg_data = PageSerializer(instance=data, many=True)
        # return Response(pg_data.data)
        return pg.get_paginated_response(pg_data.data)  # 添加一些参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 自定义示例

class MyPagination(PageNumberPagination):
    """分页器"""
    page_size = 10  # 每页数量
    page_size_query_param = 'page_size'  # 每页条数
    page_query_param = "page"  # 页码
    max_page_size = None  # 最大页码数限制

    def paginate_queryset(self, queryset, request, view=None):
        """
        Paginate a queryset if required, either returning a
        page object, or `None` if pagination is not configured for this view.
        """
        page_size = self.get_page_size(request)
        if not page_size:
            return None

        paginator = self.django_paginator_class(queryset, page_size)
        page_number = request.query_params.get(self.page_query_param, 1)
        if page_number in self.last_page_strings:
            page_number = paginator.num_pages
        try:
            self.page = paginator.page(page_number)
        except InvalidPage as exc:
            msg = self.invalid_page_message.format(
                page_number=page_number, message=str(exc)
            )
            raise NotFound(msg)

        if paginator.num_pages > 1 and self.template is not None:
            # The browsable API should display pagination controls.
            self.display_page_controls = True

        self.request = request
        return list(self.page)

    def get_page_size(self, request):
        """重写获取page_size的函数"""
        if self.page_size_query_param:
            if request.query_params.get(self.page_size_query_param) == '-1':
                self.page_size = None
            else:
                try:
                    return _positive_int(
                        request.query_params[self.page_size_query_param],
                        strict=True,
                        cutoff=self.max_page_size
                    )
                except (KeyError, ValueError):
                    pass

        return self.page_size

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
编辑 (opens new window)
版本
解析器

← 版本 解析器→

最近更新
01
配置yun源
05-24
02
linux-配置python虚拟环境
05-24
03
linux文件目录管理
05-24
更多文章>
Theme by Vdoing | Copyright © 2023-2023 yizhang | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式