django: django rest framework 分页

2018年06月22日 13:41:43 linux_player_c 阅读数:665更多

所属专栏: django 实战
 
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linux_player_c/article/details/80645969

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 分页的更多相关文章

  1. Django之REST framework源码分析

    前言: Django REST framework,是1个基于Django搭建 REST风格API的框架: 1.什么是API呢? API就是访问即可获取数据的url地址,下面是一个最简单的 Djang ...

  2. python 学习笔记十八 django深入学习三 分页,自定义标签,权限机制

    django  Pagination(分页) django 自带的分页功能非常强大,我们来看一个简单的练习示例: #导入Paginator>>> from django.core.p ...

  3. Django’s cache framework

    小结: 1.缓存存储位置:数据库.文件系统.内存 2.通过缓存前缀实现跨服务器缓存 Django’s cache framework | Django documentation | Django h ...

  4. Django的rest_framework的分页组件源码分析

    前言: 分页大家应该都很清楚,今天我来给大家做一下Django的rest_framework的分页组件的分析:我的讲解的思路是这样的,分别使用APIview的视图类和基于ModelViewSet的视图 ...

  5. python 全栈开发,Day87(ajax登录示例,CSRF跨站请求伪造,Django的中间件,自定义分页)

    一.ajax登录示例 新建项目login_ajax 修改urls.py,增加路径 from app01 import views urlpatterns = [ path('admin/', admi ...

  6. 第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页

    第三百七十节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)用Django实现搜索结果分页 逻辑处理函数 计算搜索耗时 在开始搜索前:start_time ...

  7. 第三百一十四节,Django框架,自定义分页

    第三百一十四节,Django框架,自定义分页 自定义分页模块 #!/usr/bin/env python #coding:utf-8 from django.utils.safestring impo ...

  8. django高级应用(分页功能)

    django高级应用(分页功能) 1.原生分页应用 前端html代码 <!DOCTYPE html> <html lang="en"> <head&g ...

  9. Django框架 之 Pagination分页实现

    Django框架 之 Pagination分页实现 浏览目录 自定义分页 Django内置分页 一.自定义分页 1.基础版自定义分页 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

随机推荐

  1. SP104 HIGH - Highways

    vjudge luogu 题意 就是要你求无向图的生成树个数.\(n\le 12\),保证答案不爆\(long long\). sol 矩阵树定理直接上. 如果怕掉精可以写整数意义下的高斯消元,需要辗 ...

  2. 也谈TDD,以及三层架构、设计模式、ORM……没有免费的午餐,选择了,必付出代价

    想在园子里写点东西已经很久了,但一直没有落笔,忙着做 一起帮 的开发直播,还有些软文做推广,还要做奶爸带孩子,还要……好吧,我承认,真正的原因是: 太特么的难写了! 但再难写也要写啊,要等到“能写好了 ...

  3. PADS Logic 脚本的 Fields 一个对象记录

    PADS Logic 脚本的 Fields 一个对象记录 PADS Laogic 有一个非常棒的脚本功能,可以导出所以元件. 我目前是把脚本绑定到 Ctrl+S 上,在保存时自动导出 txt 文件,方 ...

  4. Python学习系列(三)(字符串)

    Python学习系列(三)(字符串) Python学习系列(一)(基础入门) Python学习系列(二)(基础知识) 一个月没有更新博客了,最近工作上有点小忙,实在是没有坚持住,丢久又有感觉写的必要了 ...

  5. 主窗体上按钮jig画图时,CAD得不到焦点的问题

    主窗体上按钮jig画图时,CAD得不到焦点的问题    按钮不要用 Click 事件,用 MouseDown 事件, 可完美解决该问题 1.试过CAD窗体获得焦点,不顶用 2.试用用命令行去执行,可行 ...

  6. apt安装工具

    apt-cache search package 搜索包 apt-cache show package 获取包的相关信息,如说明.大小.版本等 sudo apt-get install package ...

  7. 10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides(转)

    10 Things ASP.NET Developers Should Know About Web.config Inheritance and Overrides Wednesday, Janua ...

  8. Browserify使用指南(转)

    让浏览器加载Nodejs模块 目前NPM上有二十多万个NodeJS模块,它们都是通过CMD的方式打包的,除了特定的可以使用CMD模块加载器加载的模块,大部分nodejs模块无法直接使用到浏览器环境中. ...

  9. compoer 全局和单个项目切换源 composer update killed

    演示地址: https://blog.csdn.net/hpugym/article/details/72588393 composer update killed https://cloud.ten ...

  10. druid抛出异常:javax.management.InstanceAlreadyExistsException: com.alibaba.druid:type=DruidDataSource,id=xxx

    第一种结论 (参考: https://www.cnblogs.com/youzhibing/p/6826767.html): 问题产生的根本原因还真是:同一实例被启动了两遍,Path为/SLBAdmi ...