当开始向博客中添加内容时,需要在多个页面中分隔帖子列表.Django包含了内建的分页类,从而可方便地管理分页数据.
编辑blog应用程序的views.py文件,导入Django的分页器类并调整post_list视图,如下所示:
from django.shortcuts import render, get_object_or_404 from .models import Post from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger def post_list(request): object_list = Post.published.all() # print(posts) paginator = Paginator(object_list,3) # 每页3篇 page = request.GET.get('page') try: posts = paginator.page(page) except PageNotAnInteger: # 如果page不是一个整数,那么就返回到第一页 posts = paginator.page(1) except EmptyPage: # 如果页面超出范围返回最后一页 posts = paginator.page(paginator.num_pages) return render(request, 'blog/post/list.html', {'posts': posts,'page':page}) def post_detail(request,year,month,day,post): post = get_object_or_404(Post, slug=post, status='published', publish__year=year, publish__month=month, publish__day=day) return render(request,'blog/post/detail.html',{'post': post})
分页机制的工作方式如下所示:
- 利用每个页面上显示的对象数量实例化Paginator类
- 获取便是当前页面号的page GET参数
- 调用Paginator的page()方法获得所需页面的对象
- 如果page参数并非一个整数,我们将检索结果的第一个页面.如果该参数大于最后一个页面,则检索最后一个页面
- 向模板传递页面号以及检索对象
另外,还需要创建一个模板以显示分页器,以使其包含于使用分页机制的任意模板中.在blog程序 的templates/文件夹中,创建一个新文件,将其命名为pagination.html,并向该文件中添加下列HTML代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <div class="pagination"> <span class="step-links"> {% if page.has_previous %} <a href="?page={{ page.previous_page_number }}">Previous</a> {% endif %} <span class="current"> Page{{ page.number }} of {{ page.paginator.num_pages }}. </span> {% if page.has_next %} <a href="?page={{ page.next_page_number }}">Next</a> {% endif %} </span> </div> </body> </html>
分页模板期望接收一个Page对象,以渲染上一个和下一个连接,并显示结果的当前页和全部页.下面返回至blog/post/list.html模板,并在{% content %}块下方包含pagination.html模板,如下所示:
由于传递至模板的Page对象称作posts,因而可在帖子列表模板中包含分页模板,经参数传递后实现正确的渲染.此外,可遵循这一方法并在不同模型的分页视图中复用分页模板.
在浏览器中输入http://127.0.0.1:8000/blog/,随后可以看到帖子列表下方的分页功能,如图: