前言

继续Django后端开发系列文章。刚好遇到一个分页的需求,就记录一下。

Django作为一个“全家桶”型的框架,本身啥都有,分页组件也是有的,但默认的分页组件没有对API开发做优化,所以DjangoRestFramework这个专门写API的框架又把Django的分页组件包装了一层,集成在viewsets里的时候会更方便。

不过我们不可能一直用viewsets,有一部分API还是要用自由度更高的ApiView的,但ApiView里又没办法直接使用默认的分页组件,这时我们就需要封装一下。

并且DjangoRestFramework默认的分页信息也不够全,比如没有总页数,这点我们也可以在封装的时候魔改一下。

DRF中的分页方式

DRF中为我们封装了三种分页方式,分别是:

  • PageNumberPagination:顾名思义,不解释
  • LimitOffsetPagination:Offset分页
  • CursorPagination:加密分页

本文打算只介绍最常用的第一种,后面两种同时也会做封装,但篇幅关系就不介绍了,有兴趣的同学可以尝试使用一下。

开始代码

首先还是在我们的「DjangoStarter」项目中,在utils目录下新建一个名为paginator的Python Package。

因为代码不多,我们直接写在utils/paginator/__init__.py文件下就好。

from collections import OrderedDict

from django.core.paginator import Paginator
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
from rest_framework.response import Response class NumberPaginator(PageNumberPagination):
"""页码分页"""
def __init__(
self,
page_size,
page_size_query_param='page_size',
page_query_param='page',
max_page_size=None
):
"""
初始化分页 :param page_size: 每页显示多少条
:param page_size_query_param: URL中每页显示条数的参数
:param page_query_param: URL中页码的参数
:param max_page_size: 最大页码数限制
"""
self.page_size = page_size
self.page_size_query_param = page_size_query_param
self.page_query_param = page_query_param
self.max_page_size = max_page_size def get_paginated_response(self, data):
paginator: Paginator = self.page.paginator return Response(OrderedDict([
('total_item_count', paginator.count),
('page_count', paginator.num_pages),
('page_number', self.page.number),
('page_size', self.page_size),
('next', self.get_next_link()),
('previous', self.get_previous_link()),
('results', data)
])) class LimitOffsetPaginator(LimitOffsetPagination):
"""Offset分页"""
default_limit = 1
limit_query_param = 'limit'
offset_query_param = 'offset'
max_limit = 999 class CursorPaginator(CursorPagination):
"""加密分页"""
cursor_query_param = 'cursor'
page_size = 1
ordering = '-id' # 重写要排序的字段

针对前面说的“DjangoRestFramework默认的分页信息也不够全”问题,我重写了get_paginated_response方法,在返回值中加入这几个参数

  • page_count:总页数
  • page_number:当前页码
  • page_size:每页数量

然后另外两个参数也改了名字,更直观,更符合我们平时的开发习惯。

...

这样就完成了封装,我们接下来在代码里测试一下

测试接口

来写个测试接口看看效果

from utils.paginator import NumberPaginator

@swagger_auto_schema(
method='get', operation_summary='测试分页功能',
manual_parameters=[
openapi.Parameter('page', openapi.IN_QUERY, type=openapi.TYPE_NUMBER),
openapi.Parameter('page_size', openapi.IN_QUERY, type=openapi.TYPE_NUMBER),
])
@api_view()
def test_page(request):
# 测试数据
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
paginator = NumberPaginator(request.query_params.get('page_size', 10))
return paginator.get_paginated_response({
'data': paginator.paginate_queryset(queryset=data, request=request)
})

配置一下路由

urlpatterns = [
path('test_page', views.test_page),
]

测试效果

写完的接口接受两个参数,pagepage_size,我在@swagger_auto_schema装饰器里声明了这两个参数,方便我们在Swagger文档中做测试。

我们设定page_size=5,拿到的JSON数据是这样的:

{
"message": "请求成功",
"code": 200,
"data": {
"total_item_count": 10,
"page_count": 2,
"page_number": 1,
"page_size": "5",
"next": "http://127.0.0.1:8005/core/test_page?page=2&page_size=5",
"previous": null,
"results": {
"data": [
1,
2,
3,
4,
5
]
}
}
}

效果不错,很清晰。

收工。

参考资料

DjangoRestFramework框架三种分页功能的实现 - 在DjangoStarter项目模板中封装的更多相关文章

  1. Asp.Net中的三种分页方式

    Asp.Net中的三种分页方式 通常分页有3种方法,分别是asp.net自带的数据显示空间如GridView等自带的分页,第三方分页控件如aspnetpager,存储过程分页等. 第一种:使用Grid ...

  2. 带分页功能的SSH整合,DAO层经典封装

    任何一个封装讲究的是,使用,多状态.Action:     任何一个Action继承分页有关参数类PageManage,自然考虑的到分页效果,我们必须定义下几个分页的参数.并根据这个参数进行查值. 然 ...

  3. 命令stat anaconda-ks.cfg会显示出文件的三种时间状态(已加粗):Access、Modify、Change。这三种时间的区别将在下面的touch命令中详细详解:

    7.stat命令 stat命令用于查看文件的具体存储信息和时间等信息,格式为"stat 文件名称". stat命令可以用于查看文件的存储信息和时间等信息,命令stat anacon ...

  4. AIR32F103(三) Linux环境基于标准外设库的项目模板

    目录 AIR32F103(一) 合宙AIR32F103CBT6开发板上手报告 AIR32F103(二) Linux环境和LibOpenCM3项目模板 AIR32F103(三) Linux环境基于标准外 ...

  5. Sql三种分页方法

    --分页三种方法--第一种 ROW_NUMBER() OVER( ORDER BY OrgID) AS indexs 大于pagesize*pageindex,少于等于pagesize*(pagein ...

  6. sqlserver三种分页方式性能比较

    Liwu_Items表,CreateTime列建立聚集索引 第一种,sqlserver2005特有的分页语法 declare @page intdeclare @pagesize intset @pa ...

  7. T-sql中的三种分页查询

    USE [APS_Future_FT] GO /****** Object: StoredProcedure [dbo].[A_PagingAndSorting] Script Date: 2013/ ...

  8. Asp.Net中的三种分页方式总结

    本人ASP.net初学,网上找了一些分页的资料,看到这篇文章,没看到作者在名字,我转了你的文章,只为我可以用的时候方便查看,2010的文章了,不知道这技术是否过期. 以下才是正文 通常分页有3种方法, ...

  9. 获取class对象的三种方法以及通过Class对象获取某个类中变量,方法,访问成员

    public class ReflexAndClass { public static void main(String[] args) throws Exception { /** * 获取Clas ...

随机推荐

  1. Django orm Q查询补充

    Q的简单用法 from django.db.models import Q q = Q() q.children.append(("username", "lyj&quo ...

  2. corn计划周期任务

                                                                             corn计划任务 1.计划任务有四种方式   cron ...

  3. 统计分析— 1.SPSS数据编辑窗口 输出窗口 语法窗口

    第一课-SPSS窗口 一 数据编辑窗口(Data Editor) 二 输出窗口(Output Viewer ) 三 语法窗口(Syntax Editor):针对中高级用户,有些操作可以通过输入代码的方 ...

  4. synchronized已经不在臃肿了,放下对他的成见之初识轻量级锁

    前言 物竞天择,适者生存.JDK也在不断的优化中.关于JDK中synchronized锁内部也是不断的优化,前面我们分析了偏向锁用来解决初期问题,随着争抢的不断堆积轻量级锁营运而生. 关注我,一个不断 ...

  5. HTTPS-各种加密方式

    推荐阅读:https://www.cnblogs.com/zwtblog/tag/计算机网络/ 目录 HTTPS 对称加密(AES) 非对称加密(RSA) 工作过程 分析 优缺点 常用算法 混合加密 ...

  6. docker容器登录,退出等操作命令

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口 ...

  7. XML文档约束有哪几种?有什么区别?

    XML DTD(功能有限) XML Schema (功能强大) Schema本身是XML的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的),Schema支持命名空间,Schema ...

  8. pyinstaller打包Django项目

    系统:ubuntu18.04 / Centos 7自带Python3.61.安装pip3     apt-get install -y python3-pip     pip3 install --u ...

  9. elasticsearch 5.6.7在线安装ik分词,亲测有效

    官网的在线安装命令 ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/rele ...

  10. 数据结构:DHU顺序表ADT模板设计及简单应用:找匹配

    顺序表ADT模板设计及简单应用:找匹配 时间限制: 1S类别: DS:线性表->线性表应用 问题描述: 输入范例: 100000100000 99999 99998 99997 99996 99 ...