博文数量如果很多的话,按照目前的文章列表可能会出现大量的文章,不仅影响美观,也会影响到网站的运行速度。
这个时候我们就需要进行分页处理。
Django也贴心的给我们提前准备好了轮子了,我们装上就可以用了。
文章分页我们用到的是Paginator
类。
类Paginator 说明
Paginator 类的构造方法是:
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
1.类参数
其中必选参数为:
object_list
:分页的列表对象per_page
:每页的条目数目的最大值
可选参数:
orphans=0
: 当你使用此参数时说明你不希望最后一页只有很少的条目。如果最后一页的条目数少于等于orphans的值,则这些条目会被归并到上一页中(此时的上一页变为最后一页)。例如有23项条目, per_page=10,orphans=0,则有3页,分别为10,10,3.如果orphans>=3,则为2页,分别为10,13。allow_empty_first_page=True
: 默认允许第一页为空。
2.类方法:
Paginator.page(number)
:根据参数number返回一个Page对象。(number为1的倍数)
3.类属型:
Paginator.count
:所有页面对象总数,即统计object_list中item数目。当计算object_list
所含对象的数量时, Paginator会首先尝试调用object_list.count()
。如果object_list
没有count()
方法,Paginator
接着会回退使用len(object_list)
。Pagnator.num_pages:
页面总数。pagiator.page_range
:页面范围,从1开始,例如[1,2,3,4]。
视图中使用Paginator
要对文章列表分页,因此就要修改article/views.py
的def article_list()
视图:
# 引入分页模块
from django.core.paginator import Paginator
def article_list(request):
# # 取出所有博客文章
# articles = Article.objects.all()
# 修改变量名称(articles -> article_list)
article_list = Article.objects.all()
# 每页显示 1 篇文章
paginator = Paginator(article_list, 1)
# 获取 url 中的页码
page = request.GET.get('page')
# 将导航对象相应的页码内容返回给 articles
articles = paginator.get_page(page)
# 需要传递给模板(templates)的对象
context = {'articles': articles}
# render函数:载入模板,并返回context对象
return render(request, 'article/list.html', context)
在视图中通过Paginator
类,给传递给模板的内容做了手脚:
返回的不再是所有文章的集合,而是对应页码的部分文章的对象,并且这个对象还包含了分页的方法。
我们在前面的文章已经接触过一些将参数传递到视图的手段了:
- 通过
POST
请求将表单数据传递到视图 - 通过
url
将地址中的参数传递到视图
这里用到了另一种方法:在GET
请求中,在url的末尾附上?key=value
的键值对,视图中就可以通过request.GET.get('key')
来查询value的值。
然后改写模板,在最末尾的</div>前面,加入分页的内容:
<!-- 页码导航 -->
<div class="pagination row">
<div class="m-auto">
<span class="step-links">
<!-- 如果不是第一页,则显示上翻按钮 -->
{% if articles.has_previous %}
<span>...</span>
<a href="?page={
{ articles.previous_page_number }}"
class="btn btn-secondary"
>
{
{ articles.previous_page_number }}
</a>
{% endif %}
<!-- 当前页面 -->
<span class="current btn btn-danger btn-lg">
{
{ articles.number }}
</span>
<!-- 如果不是最末页,则显示下翻按钮 -->
{% if articles.has_next %}
<a href="?page={
{ articles.next_page_number }}&order={
{ order }}"
class="btn btn-secondary">{
{ articles.next_page_number }}</a>
<span>...</span>
<a href="?page={
{ articles.paginator.num_pages }}&order={
{ order }}"
class="btn btn-success">{
{ articles.paginator.num_pages }} »</a>
{% endif %}
</span>
</div>
</div>
运行服务器,成功实现分页功能。