当我们的网站数据量较大时,将其全部显示在一张页面上会导致页面加载速度变慢,用户体验也会大打折扣。在这种情况下,通常会采用分页器(Paginator)这一工具来将数据分页展示,提高页面加载速度和用户体验。
以下是 Django Paginator 分页器的使用示例的完整攻略:
1. 安装 Paginator
Django 自带了 Paginator 工具,不需要单独安装。
2. 在视图函数中使用分页器
我们需要在视图函数中进行分页器的设置。具体实现方式如下:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def my_view(request):
# 获取数据列表
object_list = MyModel.objects.all()
# 每页显示条数,可以更改
page_size = 25
# 创建分页对象,传入列表和每页显示条数
paginator = Paginator(object_list, page_size)
# 获取当前页数
page_number = request.GET.get('page')
try:
# 获取当前页的对象列表
page_obj = paginator.get_page(page_number)
except PageNotAnInteger:
# 如果当前页数不是整数,返回第一页
page_obj = paginator.get_page(1)
except EmptyPage:
# 如果当前页数大于总页数,返回最后一页
page_obj = paginator.get_page(paginator.num_pages)
return render(request, 'my_template.html', {'page_obj': page_obj})
以上是一个基础的分页器设置,在视图函数中需要进行的操作分别包括:
- 获取数据列表;
- 定义每页显示的条目数(可以自己设置);
- 创建分页对象,传入数据列表和每页显示的条目数;
- 获取当前页号,使用
request.GET.get('page')
方法; - 使用
paginator.get_page(page_number)
方法获取当前页对象; - 根据当前页的页号进行异常处理,防止错误。
3. 在模版中设置分页器
通过在视图函数中传递分页对象 page_obj
,在模板中进行分页器的设置,包括以下几个方面:
- 展现数据列表;
- 展现分页导航条:包括上一页、下一页、首页、尾页等相关链接;
- 展现页码:类似于
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...
的效果; - 样式调整。
{% if page_obj %}
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page=1" aria-label="First"><span aria-hidden="true">«</span></a></li>
<li><a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous"><span aria-hidden="true"><</span></a></li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if num == page_obj.number %}
<li class="active"><span>{{ num }}</span></li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true">></span></a></li>
<li><a href="?page={{ page_obj.paginator.num_pages }}" aria-label="Last"><span aria-hidden="true">»</span></a></li>
{% endif %}
</ul>
{% endif %}
以上是一个简单的分页导航条设置,其中:
?page={{ page_obj.previous_page_number }}
可以返回上一页;?page={{ page_obj.next_page_number }}
可以返回下一页;?page={{ page_obj.paginator.num_pages }}
可以返回最后一页。
4. 分页的示例说明
示例一:
考虑一个博客网站首页,需要展示最新的 10 篇文章,每页 5 篇文章,需要设置分页器。
# views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from channel.models import Article
def home(request):
articles = Article.objects.order_by('-pub_time')[:10]
paginator = Paginator(articles, 5)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'home.html', {
'page_obj': page_obj
})
<!-- home.html -->
{% if page_obj %}
<!-- 数据展示 -->
{% for article in page_obj %}
<div>
<h2>{{ article.title }}</h2>
<p>{{ article.pub_time }}</p>
<p>{{ article.content }}</p>
</div>
{% endfor %}
<!-- 分页导航 -->
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page=1" aria-label="First"><span aria-hidden="true">«</span></a></li>
<li><a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous"><span aria-hidden="true"><</span></a></li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if num == page_obj.number %}
<li class="active"><span>{{ num }}</span></li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true">></span></a></li>
<li><a href="?page={{ page_obj.paginator.num_pages }}" aria-label="Last"><span aria-hidden="true">»</span></a></li>
{% endif %}
</ul>
{% endif %}
以上的代码完整实现了在网站首页展示最新的 10 篇文章,每页 5 篇文章,同时设置了分页导航条。
示例二:
考虑一个评论分页的需求,假设需要展示对某个文章的全部评论,每页 10 条评论,需要设置评论的分页器。
# views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from comment.models import Comment
def comments(request, post_id):
comments = Comment.objects.filter(post_id=post_id)
paginator = Paginator(comments, 10)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'comments.html', {
'page_obj': page_obj
})
<!-- comments.html -->
{% if page_obj %}
<!-- 评论展示 -->
{% for comment in page_obj %}
<div>
<h4>{{ comment.user_name }}</h4>
<p>{{ comment.content }}</p>
<p>{{ comment.pub_time }}</p>
</div>
{% endfor %}
<!-- 分页导航 -->
<ul class="pagination">
{% if page_obj.has_previous %}
<li><a href="?page=1" aria-label="First"><span aria-hidden="true">«</span></a></li>
<li><a href="?page={{ page_obj.previous_page_number }}" aria-label="Previous"><span aria-hidden="true"><</span></a></li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if num == page_obj.number %}
<li class="active"><span>{{ num }}</span></li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li><a href="?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}" aria-label="Next"><span aria-hidden="true">></span></a></li>
<li><a href="?page={{ page_obj.paginator.num_pages }}" aria-label="Last"><span aria-hidden="true">»</span></a></li>
{% endif %}
</ul>
{% endif %}
以上的代码完整实现了在评论页面展示某个文章的全部评论,每页 10 条评论,同时设置了分页导航条。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Django Paginator分页器的使用示例 - Python技术站