自定义分页器

针对批量插入的数据,我们在前端展示的时候发现一个很严重的问题,一页展示了所有的数据,数据量太大,查看不方便

针对数据量大但又需要全部展示给用户观看的情况下,我们统一做法都是做分页处理

分页推导

首先我们需要明确的时候,get请求也是可以携带参数的,所以我们在朝后端发送查看数据的同时可以携带一个参数告诉后端我们想看第几页的数据

其次我们还需要知道一个点,queryset对象是支持索引取值和切片操作的,但是不支持负数索引情况

接下来我们就可以推导我们的自定义分页器步骤了

current_page = request.GET.get("page",1)  # 获取用户想访问的页码  如果没有 默认展示第一页
try: # 由于后端接受到的前端数据是字符串类型所以我们这里做类型转换处理加异常捕获
current_page = int(current_page)
except Exception as e:
current_page = 1
# 还需要定义页面到底展示几条数据
per_page_num = 10 # 一页展示10条数据 # 需要对总数据进行切片操作 需要确定切片起始位置和终止位置
start_page = ?
end_page = ?
"""
下面需要研究current_page、per_page_num、start_page、end_page四个参数之间的数据关系
per_page_num = 10
current_page start_page end_page
1 0 10
2 10 20
3 20 30
4 30 40 per_page_num = 5
current_page start_page end_page
1 0 5
2 5 10
3 10 15
4 15 20
可以很明显的看出规律
start_page = (current_page - 1) * per_page_num
end_page = current_page* per_page_num
"""

数据总页面获取

当我问你下面几个问题的时候,你的内心肯定是鄙视的,不信的话那就请听题

问题1:总数据有100条,每页展示10条,总共需要几页?

答案:10条

问题2:总数据有101条,每页展示10条,总共需要几页?

答案:11条

问题3:如何通过代码算出到底需要多少条?

答案:去你妹的,不会!!!

内置方法之divmod

>>> divmod(100,10)
(10, 0) # 10页
>>> divmod(101,10)
(10, 1) # 11页
>>> divmod(99,10)
(9, 9) # 10页
# 余数只要不是0就需要在第一个数字上加一
我们可以判断元祖的第二个数字是否为0从而确定到底需要多少页来展示数据 book_queryset = models.Book.objects.all()
all_count = book_queryset.count() # 数据总条数
all_pager, more = divmod(all_count, per_page_num)
if more: # 有余数则总页数加一
all_pager += 1
至此分页器大致的功能及思路我们就已经大致清楚了 最后我们只需要利用start_page和end_page对总数据进行切片取值再传入前端页面就能够实现分页展示 book_list = models.Book.objects.all()[start_page:end_page]
return render(request,'booklist.html',locals())
接下来就是前端页面的代码编写了 {% for book in book_list %}
<p>{{ book.title }}</p>
{% endfor %}

现在我们实现了最简单的分页,但是前端没有按钮去让用户点击需要看第几页,所以我们需要渲染分页器相关代码,这里我们不做要求直接去bootstrap框架拷贝代码即可

终极大法

上面是自定义分页器开发流程的基本思路,我们不需要掌握代码的编写,只需要掌握基本用法即可

自定义分页器封装代码

class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1 if current_page < 1:
current_page = 1 self.current_page = current_page self.all_count = all_count
self.per_page_num = per_page_num # 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2) @property
def start(self):
return (self.current_page - 1) * self.per_page_num @property
def end(self):
return self.current_page * self.per_page_num def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1 # 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1 page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page) if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,) page_html_list.append(prev_page) for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp) if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page) last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)

自定义分页器使用

后端

 def get_book(request):
book_list = models.Book.objects.all()
current_page = request.GET.get("page",1)
all_count = book_list.count()
page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
page_queryset = book_list[page_obj.start:page_obj.end]
return render(request,'booklist.html',locals())

前端

<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
{% for book in page_queryset %}
<p>{{ book.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
</div>
</div>
</div>

 
 

Django基础之自定义分页器的更多相关文章

  1. django中的自定义分页器

    1.什么是自定义分页器 当我们需要在前端页面展示的数据太多的时候,我们总不能将数据展示在一页上面吧!这时,我们就需要自定义一个分页器,将数据分成特定的页数进行展示,每一页展示固定条数的数据! 2.为什 ...

  2. django自定义分页器

    一 django 的分页器 1 批量创建数据 批量导入数据: Booklist=[] for i in range(100): Booklist.append(Book(title="boo ...

  3. {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证

    Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...

  4. Django分页器和自定义分页器

    一.自定义分页器 import copy class Pagination(): def __init__(self,request,current_page,all_data_num,each_pa ...

  5. Django分页器及自定义分页器

    Django的分页器 view from django.shortcuts import render,HttpResponse # Create your views here. from app0 ...

  6. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  7. Django基础(2)--模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介

    没整理完 昨日回顾: 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 ...

  8. day 65 Django基础之django分页

      Django基础之django分页   一.Django的内置分页器(paginator) view from django.shortcuts import render,HttpRespons ...

  9. day 61 Django基础之django分页

      Django基础之django分页 一.Django的内置分页器(paginator) view   from django.shortcuts import render,HttpRespons ...

随机推荐

  1. Tensorflow Probability Distributions 简介

    摘要:Tensorflow Distributions提供了两类抽象:distributions和bijectors.distributions提供了一系列具备快速.数值稳定的采样.对数概率计算以及其 ...

  2. C++入门教程之二:变量

    C++入门教程之二:变量 变量,顾名思义,意思是变化的量.变量的定义是计算机语言中能储存计算结果或能表示值的抽象概念.一个基本的程序需要变量,因此变量是程序设计中的一大重点. 变量基本结构 var_t ...

  3. Codeforces Round #713 (Div. 3)AB题

    Codeforces Round #713 (Div. 3) Editorial 记录一下自己写的前二题本人比较菜 A. Spy Detected! You are given an array a ...

  4. Beta——事后分析

    事后总结 NameNotFound 团队 项目 内容 北航-2020-软件工程(春季学期) 班级博客 要求 Beta事后分析 课程目标 通过团队合作完成一个软件项目的开发 会议截图 一.设想和目标 软 ...

  5. [bug] Python AttributeError: module 'web' has no attribute 'application'

    原因 文件名是web.py,与包名web冲突 解决 重命名文件,再运行

  6. gparted 当分区空间大于1T 用gparted分区

    lsblkfdisk -lparted -s /dev/sdb mklabel msdos parted -s /dev/sdb mkpart primary 0 100%lsblk dfparted ...

  7. Deepin深度应用商店和系统更新不正常的解决方法

    Deepin深度应用商店和系统更新不正常的解决方法 2020-02-04 10:25:09作者:i8520稿源:深度站 如果你的Deepin深度应用商店和系统更新不正常,可采用以下方法来解决问题. 解 ...

  8. 二进制部署K8S-2集群部署

    二进制部署K8S-2集群部署 感谢老男孩教育王导的公开视频,文档整理自https://www.yuque.com/duduniao/k8s. 因为在后期运行容器需要有大量的物理硬件资源使用的环境是用的 ...

  9. 如何对你的Linux系统进行基准测试: 3开源基准测试工具

    如何对你的Linux系统进行基准测试: 3开源基准测试工具   0 赞0 评论 文章标签:SYS  Source  benchmark  tool  开源  基准  系统     linux实用程序的 ...

  10. linux基础之权限管理

    本节内容 1. 权限类别 属主(owner) 属组(group) 其他人(other) 2. 查看权限 ls -l 十位: 第一位文件类型-,d,l, 3. 设置权限 chmod 选项 权限模式 fi ...