分页的实现
Posted paulwhw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分页的实现相关的知识,希望对你有一定的参考价值。
分页的实现
简述
对于“分页”,大家肯定再熟悉不过了,当一个网页的同类的内容在一页显示不全的时候,我们通常的解决方案都是在本页的同一区域做一个类似于“翻书”的功能,在‘第1页’显示前几条内容,‘第2页’显示另外的内容,以此类推,本文就为大家介绍在Django中如何实现分页功能
功能预览
本博客系统的分页功能预览如下:
详细介绍
后台处理逻辑
首先,我们需要引入Paginator
与EmptyPage
类,后续的处理都需要依赖于这两个类。
接着,在index主页的视图函数中,我们不仅要获取本网站需要显示的所有文章的列表,还需要进行分页逻辑的处理。
分页逻辑的设计分为下面几步
一:
首先,要确定每一页显示数据的个数,也就是说在获取所有文章的前提下利用Paginator
类实例化出一个分页器对象来(我们这里限定每页显示三篇文章):
article_list = models.Article.objects.all()
paginator = Paginator(article_list,3)
注意,第一步实例化出的Paginator对象有三个参数需要大家记住,大家可以中途打印出来验证一下。
paginator.count 数据的总数
paginator.num_pages 总页数
paginator.page_range 页码的列表
二:
接下来需要将当前页面对象current_page
取出来
# 当前页,默认是第一页
current_page_c = int(request.GET.get(‘page‘, 1))
current_page = paginator.page(current_page_c)
三:
其实在数据量小的情况下做完前两部就OK了。但是大家考虑下,如果我们的数据量特别大,大到需要分100多页甚至更多时才能显示完所有的数据,这样在网页中将会有100甚至更多的分页器数据。这样显然是不合理的。为了解决这个问题,我们还需要往模板中返回range对象
,用来限制网站中分页器的页码显示:
# 最多显示11个格子
# 注意下面的判断——保证最多显示11个格子且“左5右5”,如果有越限的进行限制
# page_range_whw存的是range对象
if paginator.num_pages > 11:
# “左5”越限
if current_page_c - 5 < 1:
page_range_whw = range(1, 11)
# “右5”越限
elif current_page_c + 5 > paginator.num_pages:
page_range_whw = range(paginator.num_pages - 10, paginator.num_pages + 1)
else:
page_range_whw = range(current_page_c - 5, current_page_c + 6)
else:
page_range_whw = paginator.page_range
后台完整代码
注意,对于分页器,往后台传了两个对象,一个是当前页对象current_page
,另外一个是range对象page_range_whw
article_list = models.Article.objects.all()
paginator = Paginator(article_list, 3)
# print("count:", paginator.count) # 数据总数
# print("num_pages", paginator.num_pages) # 总页数
# print("page_range", paginator.page_range) # 页码的列表
try:
# 当前页,默认是第一页
current_page_c = int(request.GET.get(‘page‘, 1))
current_page = paginator.page(current_page_c)
# 最多显示11个格子
# 注意下面的判断——保证最多显示11个格子且“左5右5”,如果有越限的进行限制
# page_range_whw存的是range对象
if paginator.num_pages > 11:
# “左5”越限
if current_page_c - 5 < 1:
page_range_whw = range(1, 11)
# “右5”越限
elif current_page_c + 5 > paginator.num_pages:
page_range_whw = range(paginator.num_pages - 10, paginator.num_pages + 1)
else:
page_range_whw = range(current_page_c - 5, current_page_c + 6)
else:
page_range_whw = paginator.page_range
except EmptyPage as e:
current_page = paginator.page(1)
return render(request,‘index.html‘,locals())
前端模板的渲染
对于前端模板的渲染比较简单,这里就不做详细的介绍了,但是,需要注意的一点是,由于我们做了分页器,那么在‘遍历‘文章列表的时候,我们遍历的对象不再是‘article_list’了,而是当前页对象‘current_page‘
,这一点要特别注意!
文章列表渲染与分页器前端实现的代码
{# 文章列表部分 #}
<div class="col-md-6">
<div class="article-list" style="position: fixed;width: 46%;">
{# 注意,做分页的时候,循环“当前页”而不是所有的article_list #}
{% for article in current_page %}
<div class="article-item">
<h5><a href="/{{ article.user }}/articles/{{ article.pk }}/">{{ article.title }}</a></h5>
<div class="article-desc">
<span class="media-left">
{# 正向查询按字段 #}
<a href=""><img width="55px" height="55px" src="media/{{ article.user.avatar }}" ></a>
</span>
<span class="media-right">
{{ article.desc }}
</span>
</div>
<div class="small pub_info">
{# 正向查询按字段 #}
<span><a href="">{{ article.user.username }}</a></span>
<span><a href="">发布于 {{ article.create_date|date:‘Y-m-d H:i‘ }}</a></span>
<span class="glyphicon glyphicon-comment"></span>评论({{ article.content_count }})
<span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article.up_count }})
<hr>
</div>
</div>
{% endfor %}
</div>
{# 分页器 #}
<div style="position: fixed;margin-top: 38%">
<nav aria-label="Page navigation">
<ul class="pagination">
{% if current_page.has_previous %}
<li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span></a></li>
{% else %}
<li class="disabled"><a href="" aria-label="Previous">
<span aria-hidden="true">上一页</span></a></li>
{% endif %}
{% for item in page_range_whw %}
{% if current_page_c == item %}
<li class="active"><a href="?page={{ item }}">{{ item }}</a></li>
{% else %}
<li><a href="?page={{ item }}">{{ item }}</a></li>
{% endif %}
{% endfor %}
{% if current_page.has_next %}
<li><a href="?page={{ current_page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">下一页</span></a></li>
{% else %}
<li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">下一页</span></a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
以上是关于分页的实现的主要内容,如果未能解决你的问题,请参考以下文章