django: django rest framework 分页
django: django rest framework 分页
django rest framework pagination
在drf中对于数据的返回支持多种分页技巧,在官网中主要向我们介绍了PageNumberPagination、LimitOffsetPagination、CursorPagination。
本课程的讲解使用示例项目,该项目的目录结构如下所示:
目录结构
该目录结构与django原生的目录结构差异较大,其中所有的django应用都在apps目录中,目前拥有assets和rbac两个应用。conf内存放的是urls,py和wsgi.py文件,在settings目录中写入了该项目的配置文件base.py。
对于drf的分页可以采用全局配置和对每个视图进行单独配置的方法。
如果采用全局配置需要在配置文件中设置,例如将全局分页设置为PageNumberPagination,需要在base.py中添加如下配置:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100
}
- 1
- 2
- 3
- 4
如果需要对每个视图进行单独配置,需要设置ModelViewSet中的pagination_class值,示例如下:
class MachineRoomViewSet(viewsets.ModelViewSet):
"""
机房操作视图
"""
queryset = MachineRoom.objects.all()
serializer_class = MachineRoomSerializer
pagination_class = PageNumberPagination
- 1
- 2
- 3
- 4
- 5
- 6
- 7
下面分别介绍这三个的使用方法:
PageNumberPagination
此分页样式在请求查询参数中接受单个号码页码。用户可以指定访问的页数,示例如下:
GET http://127.0.0.1:8060/assets/v1/regions/?page=2
- 1
返回的内容如下:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"results": [
{
"id": 3,
"region_name": "华西",
"created_time": "2018-06-20T08:52:32.871964Z",
"modified_time": null
},
{
"id": 4,
"region_name": "华北",
"created_time": "2018-06-20T14:47:46.910065Z",
"modified_time": null
}
],
"pagination": 4,
"page_size": 2,
"page": 2
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
按照页数访问是比较常见的一种做法,所以我们大多数情况使用PageNumberPagination,上述的返回结果集进行了调整,这是继承PageNumberPagination类,对其get_paginated_response函数的返回内容格式进行了再定义。
后续在介绍自定义分页格式时会进行详细介绍。PageNumberPagination的默认返回格式为:
HTTP 200 OK
{
"count": 1023
"next": "https://api.example.org/accounts/?page=5",
"previous": "https://api.example.org/accounts/?page=3",
"results": [
…
]
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
包含next(下一页)和previous(上一页)两个跳转地址。
LimitOffsetPagination
这种分页样式反映了查找多个数据库记录时使用的语法,客户端包含“limit(限制)”和“offset(偏移量)”查询参数。
该限制表示要返回的项目的最大数量,并且等同于其他样式中的page_size。
偏移量指示查询的起始位置与完整的未分类项目集的关系。
使用这种分页方式的model进行查询的时候需要指定limit(个数)和offset(起始位置)。
GET http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=2
- 1
返回结果如下:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"count": 4,
"next": "http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=3",
"previous": "http://127.0.0.1:8060/assets/v1/regions/?limit=1&offset=1",
"results": [
{
"id": 3,
"region_name": "华西",
"created_time": "2018-06-20T08:52:32.871964Z",
"modified_time": null
}
]
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
CursorPagination
基于游标的分页提供了一个不透明的 “游标” 指示器,客户端可以使用该指示器来翻阅结果集。此分页样式仅提供前向和反向控件,并且不允许客户端导航到任意位置。
基于游标的分页需要在结果集中存在唯一的,不变的 item 顺序。这种排序通常可以是记录上的创建时间戳,因为这确保了排序的一致性。
假设我们以创建时间来进行排序,新建时间一般是无法进行修改的。该字段的内容只需要设置一次。但是时间也有可能冲突。为了避免这种重复问题,可以对该条信息的数据抽取出特征值而组合成一个唯一的字符串。例如:假设我们我们对一个云主机设置一个不会冲突的字段:可以使用如下格式“名称-规格-创建时间”,这样的一条信息应该是不会冲突的。
CursorPagination的参数配置如下:
page_size = 指定页面大小的数字值。如果设置,则会覆盖 PAGE_SIZE 设置。默认值与 PAGE_SIZE setting key 相同。
cursor_query_param = 一个字符串值,指定 “游标” 查询参数的名称。默认为 ‘cursor’.
ordering = 这应该是一个字符串或字符串列表,指定将应用基于游标的分页的字段。例如: ordering = ‘slug’。默认为 -created。该值也可以通过在视图上使用 OrderingFilter 来覆盖。
template = 在可浏览 API 中渲染分页控件时使用的模板的名称。可能会被覆盖以修改渲染样式,或设置为 None 以完全禁用 HTML 分页控件。默认为 “rest_framework/pagination/previous_and_next.html”
自定义分页类
除了drf给出的上述三种分页方法,用户可以根据自己的需求进行自定义分页以适应不同业务需求。这个可以继承并拓展drf的分页类。我们编写一个MyFormatResultsSetPagination自定义分页类,该类继承自PageNumberPagination,内容如下:
class MyFormatResultsSetPagination(pagination.PageNumberPagination):
page_size_query_param = "page_size"
page_query_param = 'page'
page_size = 2
max_page_size = 1000
"""
自定义分页方法
"""
def get_paginated_response(self, data):
"""
设置返回内容格式
"""
return Response({
'results': data,
'pagination': self.page.paginator.count,
'page_size': self.page.paginator.per_page,
'page': self.page.start_index() // self.page.paginator.per_page + 1
})
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
在get_paginated_response重写了返回格式。
如果要使用自定义分页类,只需要在ModelViewSet中设定pagination_class为自定义分类。示例如下:
class RegionViewSet(viewsets.ModelViewSet):
"""
区域操作视图
"""
queryset = Region.objects.all()
serializer_class = RegionSerializer
pagination_class = MyFormatResultsSetPagination # 自定义分页
- 1
- 2
- 3
- 4
- 5
- 6
- 7
小结
分页是后端restful接口一个非常常见的需求,django rest framework为我们编写业务简化了很多操作。需要熟练掌握。
django: django rest framework 分页的更多相关文章
- Django之REST framework源码分析
前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...
- python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制
django Pagination(分页) django 自带的分页功能非常强大,我们来看一个简单的练习示例: #导入Paginator>>> from django.core.p ...
- Django’s cache framework
小结: 1.缓存存储位置:数据库.文件系统.内存 2.通过缓存前缀实现跨服务器缓存 Django’s cache framework | Django documentation | Django h ...
- Django的rest_framework的分页组件源码分析
前言: 分页大家应该都很清楚,今天我来给大家做一下Django的rest_framework的分页组件的分析:我的讲解的思路是这样的,分别使用APIview的视图类和基于ModelViewSet的视图 ...
- python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)
一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...
- 第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页
第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页 逻辑处理函数 计算搜索耗时 在开始搜索前:start_time ...
- 第三百一十四节,Django框架,自定义分页
第三百一十四节,Django框架,自定义分页 自定义分页模块 #!/usr/bin/env python #coding:utf-8 from django.utils.safestring impo ...
- django高级应用(分页功能)
django高级应用(分页功能) 1.原生分页应用 前端html代码 <!DOCTYPE html> <html lang="en"> <head&g ...
- Django框架 之 Pagination分页实现
Django框架 之 Pagination分页实现 浏览目录 自定义分页 Django内置分页 一.自定义分页 1.基础版自定义分页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
随机推荐
- Android应用框架-Volley网络通信框架
1.Volley简介: Volley是Google 推出的 Android 异步网络请求框架和图片加载框架. 在 Google I/O 2013 大会上发布. 2.Volley特点 扩展性强. And ...
- UNION和UNION ALL关键字
UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同. 1.对重复结果的处理:UNION在进行表链接后会筛选掉重复的记录,Union All不会去除重复 ...
- 【转】JMeter脚本的参数化
JMeter脚本的参数化 当你利用Badboy将你的测试脚本录制完毕后,接下来就是脚本的调试工作了.在我看来,调试应该包括有以下几个方面:1.根据测试场景对脚本进行必要的修改:2.脚本参数化:3.添加 ...
- 《转载》ubuntu Sublime text 3 解决中文输入问题
其实,在这个文章之前,网上都有好多教程了.不知道是不是因为复制黏贴的传播太多,导致有些字符串的丢失,导致编译失败,so库文件无法载入,从而不能输入中文.折腾了许久之后,终于搞定了.记录下来,方便自己下 ...
- Oracle redo与undo
Undo and redo Oracle最重要的两部分数据,undo 与redo,redo(重做信息)是oracle在线(或归档)重做日志文件中记录的信息,可以利用redo重放事务信息,undo(撤销 ...
- python开发面向对象基础:组合&继承
一,组合 组合指的是,在一个类中以另外一个类的对象作为数据属性,称为类的组合 人类装备了武器类就是组合 1.圆环,将圆类实例后传给圆环类 #!/usr/bin/env python #_*_ ...
- XHTML1.0版本你知道么,跟html5版本有什么区别
XHTML 1.0 是 XML 风格的 HTML 4.01. XHTML 1.1 主要是初步进行了模块化. HTML5 是下一代 HTML,取代 HTML 4.01. W3C 原本确实计划用 XHTM ...
- GNS3连接虚拟机
打开GNS3,拖一台路由器和主机 右击主机,选择配置 添加虚拟机的网卡为主机网卡,(选择VM1或VM8) 路由器选择虚拟机网卡连接 打开虚拟机在导航栏找到“虚拟机”-->“设 ...
- oracle——存储过程参数
oracle 存储过程类型: 1.in:输入类型,即由应用程序将数据传入oracle存储过程中:这种参数在存储过程中是只读参数,在存储过程中无法对该类型的参数进行修改: 2.out:输出参数,是在存储 ...
- **python中列表 元组 字典 集合
列表 元组 字典 集合的区别是python面试中最常见的一个问题.这个问题虽然很基础,但确实能反映出面试者的基础水平. 1.列表 列表是以方括号“[]”包围的数据集合,不同成员以“,”分隔. 列表的特 ...