当前位置: 首页 > news >正文

Django高级之-分页器

目录

一、引入

二、分页推导

三、数据总页面获取

四、内置方法之divmod

五、终极大法

六、自定义分页器使用

【1】后端

【2】前端


一、引入

  • 针对上一小节批量插入的数据
    • 我们在前端展示的时候发现一个很严重的问题
    • 一页展示了所有的数据,数据量太大,查看不方便
  • 针对数据量大但又需要全部展示给用户观看的情况下
    • 我们统一做法都是做分页处理

二、分页推导

  • 首先我们需要明确的时候
    • 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_page1                           0                           102                           10                          203                           20                          30  4                           30                          40per_page_num = 5
current_page                start_page                  end_page1                           0                           52                           5                           103                           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 = 1if current_page < 1:current_page = 1self.current_page = current_pageself.all_count = all_countself.per_page_num = per_page_num# 总页码all_pager, tmp = divmod(all_count, per_page_num)if tmp:all_pager += 1self.all_pager = all_pagerself.pager_count = pager_countself.pager_count_half = int((pager_count - 1) / 2)@propertydef start(self):return (self.current_page - 1) * self.per_page_num@propertydef end(self):return self.current_page * self.per_page_numdef page_html(self):# 如果总页码 < 11个:if self.all_pager <= self.pager_count:pager_start = 1pager_end = self.all_pager + 1# 总页码  > 11else:# 当前页如果<=页面上最多显示11/2个页码if self.current_page <= self.pager_count_half:pager_start = 1pager_end = self.pager_count + 1# 当前页大于5else:# 页码翻到最后if (self.current_page + self.pager_count_half) > self.all_pager:pager_end = self.all_pager + 1pager_start = self.all_pager - self.pager_count + 1else:pager_start = self.current_page - self.pager_count_halfpager_end = self.current_page + self.pager_count_half + 1page_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)

六、自定义分页器使用

【1】后端

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())

【2】前端

<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>
http://www.lryc.cn/news/239193.html

相关文章:

  • Vue-报错No “exports“ main defined in xx
  • EL-input添加双击或者单击事件
  • OpenCV快速入门:绘制图形、图像金字塔和感兴趣区域
  • Three.js相机模拟
  • Verilog基础:仿真时x信号的产生和x信号对于各运算符的特性
  • 穿越数据的迷宫-数据管理知识介绍
  • 3
  • 【python学习】基础篇-常用模块-multiprocessing模块:多进程
  • JAVA SQL
  • [Linux] 进程入门
  • 深入解析数据结构与算法之堆
  • 信息化项目质量保证措施
  • es的优势
  • sonar对webgoat进行静态扫描
  • opencv-重点知识
  • 上海亚商投顾:北证50指数大涨 机器人概念股掀涨停潮
  • 2.4G无线收发芯片 XL2400P使用手册
  • ZC序列理论学习及仿真
  • 利用OpenCV实现图片中导线的识别
  • 关于VITS和微软语音合成的效果展示(仙王的日常生活第1-2209章)
  • 普乐蛙VR航天航空巡展项目来到了第七站——绵阳科博会
  • 行情分析——加密货币市场大盘走势(11.22)
  • QT--MP3项目数据库数据表设计与实现_歌曲搜索
  • gzip 压缩优化大 XML 响应的处理方法
  • 数字化文旅系统,让景区营销变得更加简单!
  • 配置命令别名
  • zookeeper应用之分布式队列
  • 取数游戏2(动态规划java)
  • Spring Boot中配置文件生效位置
  • AIGC创作系统ChatGPT网站系统源码,支持最新GPT-4-Turbo模型