Django Rest framework三种分页方式详解


Posted in Python onJuly 26, 2019

前言

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

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

本文将详细讲述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)]

序列化类

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)

第三步 访问测试

Django Rest framework三种分页方式详解

如上图,指定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)

第三步 访问测试

Django Rest framework三种分页方式详解

***

第三种 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 # 指定分页配置器

如下图:

Django Rest framework三种分页方式详解

is ok.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用函数默认值实现函数静态变量的方法
Aug 18 Python
利用Python脚本在Nginx和uwsgi上部署MoinMoin的教程
May 05 Python
关于Django显示时间你应该知道的一些问题
Dec 25 Python
Python之读取TXT文件的方法小结
Apr 27 Python
【python】matplotlib动态显示详解
Apr 11 Python
django foreignkey(外键)的实现
Jul 29 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
Feb 26 Python
如何基于线程池提升request模块效率
Apr 18 Python
pytorch快速搭建神经网络_Sequential操作
Jun 17 Python
聊聊python中的异常嵌套
Sep 01 Python
pandas使用函数批量处理数据(map、apply、applymap)
Nov 27 Python
python 爬取豆瓣网页的示例
Apr 13 Python
浅析Windows 嵌入python解释器的过程
Jul 26 #Python
python flask几分钟实现web服务的例子
Jul 26 #Python
解决python flask中config配置管理的问题
Jul 26 #Python
Django REST framework内置路由用法
Jul 26 #Python
python flask web服务实现更换默认端口和IP的方法
Jul 26 #Python
Django 开发环境与生产环境的区分详解
Jul 26 #Python
python3发送邮件需要经过代理服务器的示例代码
Jul 25 #Python
You might like
espresso double下 咖啡粉超细时 饼压力对咖啡的影响
2021/03/03 冲泡冲煮
PHP面向接口编程 耦合设计模式 简单范例
2011/03/23 PHP
php表单提交问题的解决方法
2011/04/12 PHP
phpmail类发送邮件函数代码
2012/02/20 PHP
使用纯php代码实现页面伪静态的方法
2015/07/25 PHP
php实现的redis缓存类定义与使用方法示例
2017/08/09 PHP
动态控制Table的js代码
2007/03/07 Javascript
parseInt parseFloat js字符串转换数字
2010/08/01 Javascript
与jquery serializeArray()一起使用的函数,主要来方便提交表单
2011/01/31 Javascript
让浏览器DOM元素最后加载的js方法
2014/07/29 Javascript
js print打印网页指定区域内容的简单实例
2016/11/01 Javascript
COM组件中调用JavaScript函数详解及实例
2017/02/23 Javascript
Bootstrap 响应式实用工具实例详解
2017/03/29 Javascript
ES6新特性之Object的变化分析
2017/03/31 Javascript
基于JavaScript实现的折半查找算法示例
2017/04/14 Javascript
countUp.js实现数字滚动效果
2019/10/18 Javascript
vue实现列表拖拽排序的功能
2020/11/02 Javascript
JS实现百度搜索框
2021/02/25 Javascript
Python中文编码那些事
2014/06/25 Python
Python用模块pytz来转换时区
2016/08/19 Python
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
对Python发送带header的http请求方法详解
2019/01/02 Python
Python txt文件加入字典并查询的方法
2019/01/15 Python
解决django前后端分离csrf验证的问题
2019/02/03 Python
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
python:动态路由的Flask程序代码
2019/11/22 Python
Python itertools.product方法代码实例
2020/03/27 Python
Tensorflow中k.gradients()和tf.stop_gradient()用法说明
2020/06/10 Python
浅析NumPy 切片和索引
2020/09/02 Python
为什么UNION ALL比UNION快
2016/03/17 面试题
签约仪式主持词
2014/03/19 职场文书
2014年党员创先争优承诺书
2014/05/29 职场文书
现役军人家属慰问信
2015/03/24 职场文书
优秀志愿者感言
2015/08/01 职场文书
新手入门Mysql--概念
2021/06/18 MySQL
Vue Element plus使用方法梳理
2022/12/24 Vue.js