Django-restframework25 Pagination(分页)

2017年11月11日 15:14:36 敲代码的伪文青 阅读数:1021 标签: restful 更多

个人分类: rest-framework
 

Django提供几个类专门用于处理分页数据。意味着你的数据被切割成几页。通过Previous/Next的链接进行调用。

1 Pagination

1. 简介

REST框架支持自定义分页风格,你可以修改每页显示数据集合的最大长度。 
分页链接支持以下两种方式提供给用户: 
- 分页链接是作为响应内容提供给用户 
- 分页链接被包含在响应头中(Content-Range或者Link) 
内建风格使用作为响应内容提供给用户。这种风格更容易被使用可浏览API的用户所接受 
如果使用通用视图或者视图集合。系统会自动帮你进行分页。如果使用的是APIView,你就需要自己调用分页API,确保返回一个分页后的响应。可以将pagination_class设置为None关闭分页功能。

2. 设置分页风格

可以通过设置DEFAULT_PAGINATION_CLASS和PAGE_SIZE,设置全局变量。

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
  3. 'PAGE_SIZE': 100
  4. }
  • 1
  • 2
  • 3
  • 4

需要同时设置pagination class和page size。 
也可以在单个视图中设置pagination_class属性,一般你需要使用统一的分页风格。

3. 修改分页风格

如果你需要修改分页风格 ,系需要重写分页类,然后设置你需要修改的属性。

  1. class LargeResultsSetPagination(PageNumberPagination):
  2. page_size = 1000
  3. page_size_query_param = 'page_size'
  4. max_page_size = 10000
  5. class StandardResultsSetPagination(PageNumberPagination):
  6. page_size = 100
  7. page_size_query_param = 'page_size'
  8. max_page_size = 1000
  9. # 然后在视图中使用.pagination_class属性调用该自定义类
  10. class BillingRecordsView(generics.ListAPIView):
  11. queryset = Billing.objects.all()
  12. serializer_class = BillingRecordsSerializer
  13. pagination_class = LargeResultsSetPagination
  14. # 或者是在设置中修改DEFAULT_PAGINATION_CLASS
  15. REST_FRAMEWORK = {
  16. 'DEFAULT_PAGINATION_CLASS': 'apps.core.pagination.StandardResultsSetPagination'
  17. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

2 API指南

1. PageNumberPagination

这个分页样式接受请求查询参数中的一个数字页面号。

  1. GET https://api.example.org/accounts/?page=4
  • 1

响应对象

  1. HTTP 200 OK
  2. {
  3. "count": 1023
  4. "next": "https://api.example.org/accounts/?page=5",
  5. "previous": "https://api.example.org/accounts/?page=3",
  6. "results": [

  7. ]
  8. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

继承了GenericAPIView的视图中,也可以设置pagination_class属性选择PageNumberPagination 
配置属性: 
- django_paginator_class 
使用Django分页类。默认为django.core.paginator.Paginator,适用于大多数情况 
- page_size 
用来显示每页显示对象的数量,如果设置了就重写PAGE_SIZE设置。 
- page_query_param 
页面查询参数,一个字符串值,指示用于分页控件的查询参数的名称。 
- page_size_query_param 
该参数允许客户端根据每个请求设置页面大小。一般默认设置为None. 
- max_page_size 
只有设置了page_size_query_param参数,该参数才有意义,为客户端请求页面中能够显示的最大数量 
- last_page_strings 
用于存储使用page_query_param参数请求过的值列表或元组,默认为(‘last’,) 
- template 
用来在可浏览API中,渲染分页的模板(html)名字,可以重写分页样式,或者设置为None,禁用分页。默认为”rest_framework/pagination/numbers.html”。

2. LimitOffsetPagination

这种分页样式与查找多个数据库记录时使用的语法类似。客户端包括一个”limit”和一个 “offset”查询参数。该限制表示返回的条目的最大数量,并且与page_size大小相同。偏移量表示查询的起始位置,与完整的未分页项的集合有关。

  1. GET https://api.example.org/accounts/?limit=100&offset=400
  2. HTTP 200 OK
  3. {
  4. "count": 1023
  5. "next": "https://api.example.org/accounts/?limit=100&offset=500",
  6. "previous": "https://api.example.org/accounts/?limit=100&offset=300",
  7. "results": [

  8. ]
  9. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

使用这种风格需要设置

  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination'
  3. }
  • 1
  • 2
  • 3

显然,你也可以设置PAGE_SIZE,然后客户端就可以设置limit参数了。 
继承了GenericAPIView的子类,可以通过设置pagination_class属性为LimitOffsetPagination使用 
(重写LimitOffsetPagination类)配置: 
- default_limit: 如果客户端没有提供,则默认使用与PAGE_SIZE值一样。 
- limit_query_param:表示限制查询参数的名字,默认为’limit’ 
- offset_query_param:表示偏移参数的名字, 默认为’offset’ 
- max_limit:允许页面中显示的最大数量,默认为None 
- template: 渲染分页结果的模板名,默认为”rest_framework/pagination/numbers.html”.

3. CursorPagination

基于游标的分页显示了一个不透明的“cursor”指示器,客户端可以使用它来浏览结果集。这种分页方式只允许用户向前或向后进行查询。并且不允许客户端导航到任意位置。 
基于游标的分页要求在结果集中有一个惟一的、不变的条目顺序。这个排序通常是记录上的一个创建时间戳,用来表示分页的顺序。 
基于游标的分页比其他方案更复杂。它还要求结果集给出一个固定的顺序,并且不允许客户端任意地对结果集进行索引,但是它确实提供了以下好处: 
- 提供一致的分页视图。当使用正确的指针分页时,即使在分页过程中其他客户端插入新项时,客户端也不会在分页时看到同一个项两次。 
- 支持使用非常大的数据集。大量数据集使用基于off-set的分页方式可能会变得低效或不可用。基于指针的分页模式有固定的时间属性,并且随着数据集的大小的增加而不会减慢。

  1. 细节和局限性 
    正确地使用基于游标的分页方式需要对细节有一点注意。你需要考虑你想要什么样的命令翻转这个排序方式。默认是通过“-created”来排序的。这假设在模型实例上必须有一个“created”的时间戳字段,并将显示一个“timeline”样式的分页视图,其中最近添加的项是第一个。 
    你也可以通过’ordering’属性重写这个分页类,或者使用OrderingFilter过滤器这两种方式与CursorPagination一起使用。当使用OrderingFilter时,必须仔细考虑用来排序的字段 
    使用游标分页的字段要求:

    • 应该是一个不变的值,例如时间戳,标签,或者其他只在创建时设置的字段
    • 应该是唯一的或者近乎唯一的,使用毫秒精度的时间戳是一个很好的例子
    • 应该是一个强制表示为字符串的值
    • 该字段应该有一个数据库索引(重点) 
      不满足这些要求,也可以使用游标分页,但会失去一些游标的优点
  2. 设置全局变量
  1. REST_FRAMEWORK = {
  2. 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.CursorPagination',
  3. 'PAGE_SIZE': 100
  4. }
  • 1
  • 2
  • 3
  • 4

也可以在GenericAPIView子类中设置pagination_class属性 
3. 配置 
- page_size:显示的最大条数 
- cursor_query_param: 游标查询参数名,默认为’cursor’ 
- ordering: 排序字段名的列表或者元组,例如ordering = ‘slug’,默认为-created 
- template: 渲染模板名,默认为”rest_framework/pagination/previous_and_next.html”

3 自定义分页

  1. 继承pagination.BasePagination
  2. 重写paginate_queryset(self, queryset, request, view=None)方法 
    初始化queryset对象,设置pagination实例,返回一个只包含用户请求内容的可迭代的对象,形成分页对象
  3. 重写get_paginated_response(self, data)方法 
    序列化请求页中说包含的对象,返回一个Response对象
  1. class CustomPagination(pagination.PageNumberPagination):
  2. def get_paginated_response(self, data):
  3. return Response({
  4. 'links': {
  5. 'next': self.get_next_link(),
  6. 'previous': self.get_previous_link()
  7. },
  8. 'count': self.page.paginator.count,
  9. 'results': data
  10. })
  11. # 设置自定义分页、
  12. REST_FRAMEWORK = {
  13. 'DEFAULT_PAGINATION_CLASS': 'my_project.apps.core.pagination.CustomPagination',
  14. 'PAGE_SIZE': 100
  15. }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

请注意,如果在意在可浏览的API中如何显示键的顺序,那么您可能会选择在构建分页响应的主体时使用OrderedDict,但这是可选的。

  1. 分页模式 
    如果需要对REST框架提供的分页进行控制,可以使用get_schema_fields(self, view)方法,该方法返回一个coreapi.Field实例的列表

4 HTML分页控制

PageNumberPagination和LimitOffsetPagination使用page和previous,next进行控制 
CursorPagination仅使用 previous和next进行控制 
1. 自定义控制 
通过重写 templates。 
- rest_framework/pagination/numbers.html 
- rest_framework/pagination/previous_and_next.html 
2. 低级API 
在pagination中,display_page_controls属性将用于决定分页类是否具有控制显示的功能 
自定义pagination类在paginate_queryset()方法中应该设置为True

5 三方包

  1. DRF-extensions
  2. drf-proxy-pagination 
    提供ProxyPagination,用于允许在查询参数中设置分页类。
  3. link-header-pagination

Django-restframework25 Pagination(分页)的更多相关文章

  1. Django 利用 Pagination 分页

    Django自身提供了一些类来实现管理分页,数据被分在不同的页面中,并带有“上一页/下一页”标签.这个类叫做Pagination,其定义位于 django/core/paginator.py 中. 一 ...

  2. Django框架 之 Pagination分页实现

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

  3. Django内置分页

    一.django内置分页 from django.shortcuts import render from django.core.paginator import Paginator, EmptyP ...

  4. Django拾遗--pagination、sitemap、admin、form

    Django拾遗--pagination.sitemap.admin.form pagination 其实这个分页模块的原理就是根据设定的每页条数来分割queryset.查询结果/每页子项数目=页数 ...

  5. Django中的分页,cookies与session

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  6. django: django rest framework 分页

    django: django rest framework 分页 2018年06月22日 13:41:43 linux_player_c 阅读数:665更多 所属专栏: django 实战   版权声 ...

  7. django: rest-framework的 分页和过滤

    django: rest-framework的 分页和过滤 2018年06月28日 10:09:01 weixin_42359464 阅读数:136 标签: flaskrestframeworkdja ...

  8. django视图之分页

    在网站开发时,肯定会遇到分页的事情需要处理,在django中也是如此,在Django中处理分页一般会使用到两个类django.core.paginator.Paginator和django.core. ...

  9. django上课笔记2-视图CBV-ORM补充-Django的自带分页-Django的自定义分页

    一.视图CBV 1.urls url(r'^login.html$', views.Login.as_view()), 2.views from django.views import View cl ...

  10. Django - Xadmin (三) 分页、搜索和批量操作

    Django - Xadmin (三) 分页.搜索和批量操作 分页和 ShowList 类 因为 list_view 视图函数里面代码太多,太乱,所以将其里面的用于处理表头.处理表单数据的关键代码提取 ...

随机推荐

  1. 一起来看CORE源码(一) ConcurrentDictionary

    先贴源码地址 https://github.com/dotnet/corefx/blob/master/src/System.Collections.Concurrent/src/System/Col ...

  2. ACM学习历程—51NOD 1770数数字(循环节)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1770 这是这次BSG白山极客挑战赛的A题.由于数字全部相同,乘上b必然会 ...

  3. Java开发前期准备工作

    配置Java开发环境变量 在"系统变量"中设置3项属性,JAVA_HOME, PATH, CLASSPATH. 变量设置参数如下: 变量名:JAVA_HOME 变量值:C:\Pro ...

  4. zabbix 3.0.2自定义脚本

    http://blog.51cto.com/xiao987334176/1769766 有一个通知队列,如果超过了一定的值,就需要报警一下 查询接口可以返回队列的数量,格式是json,data后面的数 ...

  5. 发现一个github的奇葩设定

    commit时留下的邮箱,会显示在github的提交记录里,然后居然自动找服务器上的这个邮箱注册的人,显示这个用户名.

  6. SQL2005 如何在没有日志文件的情况下如何恢复MDF数据库文件?

    第一步:先建立一个同名数据库,停止SQL SERVER2005,将没有日志的的.mdf数据库文件覆盖刚新建的.mdf数据库文件,重新启动数据库. 第二步:在查询分析器中运行如下代码(将数据库名修改为您 ...

  7. Linux Shell 1>/dev/null 2>&1 含义

    shell中可能经常能看到:echo log > /dev/null 2>&1 命令的结果可以通过%>的形式来定义输出 /dev/null :代表空设备文件>  :代表 ...

  8. 显示等待 之 text_to_be_present_in_element 判断元素是否有xx 文本信息 用法

  9. 安装ElasticSearch客户端Kibana

    安装Kibana Kibana是一个为 ElasticSearch 提供的数据分析的 Web 接口.可使用它对日志进行高效的搜索.可视化.分析等各种操作. wget https://artifacts ...

  10. ecshop移动端支付宝支付对接

    初始页,提交基本信息到api页面, <?php /* * * 功能:支付宝手机网站支付接口接口调试入口页面 * 版本:3.4 * 修改日期:2016-03-08 * 说明: * 以下代码只是为了 ...