Django如何使用Future实现分页功能
一个页面无法在一页上显示所有数据项,因为要显示的数据项太多了。此时页面往往以分页的形式显示,每页显示20条或50条数据。分页在网络上随处可见。看起来是这样的:
点击查看大图
这样的实现不仅提高了用户体验,还减轻了数据库读取数据时的压力。 Django自带了一个名为Future的分页工具,可以方便我们实现分页功能。本文介绍如何使用Paginator实现分页功能。
1 Paginator
Paginator类的作用就是将我们分页需要的数据分成几部分。当我们实现一个Paginator类的实例时,我们需要传递两个参数给Paginator。第一个参数是数据源,可以是列表、元组和一组查询结果QuerySet。第二个参数必须作为整数传递,指示每页上显示的数据项数。具体写法如下:
book_list = [] for x in range(1, 26): # 一共 25 本书
book_list.append('Book ' + str(x)) # 将数据按照规定每页显示 10 条, 进行分割
paginator = Paginator(book_list, 10)
- 上面的代码中,我们传递了一个名为book_list的列表,其中包含25本书。然后我们设置Confucian每页显示10条数据,最终得到一个Confucian实例。另外,Paginator类还有三个常用的属性,分别是:
- count:表示所有页面上对象的总数。
- num_pages:表示总页数。
- page_range:索引从 1 开始的页面范围迭代器。
2 Page 对象
Paginator类提供了一个 ** page(number) ** 函数,该函数返回一个 Page 对象。参数编号代表页码。如果number = 1,则page()返回的对象是第一页的页面对象。要在前端页面显示数据,我们主要的操作都是基于Page对象。具体用法如下:
# 使用paginator对象,将页面返回到第1页。 object books = paginator.page(1)
Page对象有3个常用属性:
- object_list:标记当前对象列表页面上的所有项目。
- numbers:表示当前页面的序号,从1开始计数。
- paginator:当前Page对象所属的Paginator对象。
另外,Page 对象还有几个常用的函数:
- has_next():判断是否还有其他页面,如果有则返回 True。
- has_previous():判断是否有上一页,有则返回True。
- has_other_pages():判断这是上一页还是下一页,如果是,则返回True。
- next_page_number():返回下一页的页码。如果下一页不存在,则抛出 InvalidPage 异常。
- previous_page_number():返回上一页的页码。如果上一页不存在,则抛出 InvalidPage 异常。
- 在views.py中获取所有需要显示的数据,然后使用Paginator类对数据进行分页,最后返回第一页的page对象。页面的对象起着很大的作用。首先,它显示当前分页数据,同时还提供获取后续分页数据的接口。
- 3 应用程序 下面是我编写的一个示例程序,用于演示如何使用 Kongfun 和 Page。
- 3.1 视图
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage, InvalidPage
from django.http import HttpResponse
from django.shortcuts import render
def paginator_view(request):
book_list = [] ''' 数据通常是从 models 中获取。这里为了方便,直接使用生成器来获取数据。 '''
for x in range(1, 26): # 一共 25 本书
book_list.append('Book ' + str(x)) # 将数据按照规定每页显示 10 条, 进行分割
paginator = Paginator(book_list, 10)
if request.method == "GET": # 获取 url 后面的 page 参数的值, 首页不显示 page 参数, 默认值是 1
page = request.GET.get('page')
try:
books = paginator.page(page) # todo: 注意捕获异常
except PageNotAnInteger: # 如果请求的页数不是整数, 返回第一页。
books = paginator.page(1) except InvalidPage: # 如果请求的页数不存在, 重定向页面
return HttpResponse('找不到页面的内容')
except EmptyPage: # 如果请求的页数不在合法的页数范围内,返回结果的最后一页。
books = paginator.page(paginator.num_pages)
template_view = 'page.html'
return render(request, template_view, {'books': books})
3.2 模板 模板的任务是用数据填充 HTML 页面。当您获取视图传递的书籍(书籍是 Page 对象)时,在 for 循环中打印数据。最后使用Books根据页面情况显示上一页按钮、当前页码、总页数、下一页按钮。
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html">
<head> <meta charset="UTF-8">
<link href="{%%20static%20'css/bootstrap.min.css'%20%}" rel="stylesheet">
<script ></script>
<script ></script>
<title>分页</title>
</head>
<br>
<div class="text-center" >
{% for book in books %} <span>书名: {{ book }} <br /></span>
{% endfor %} </div> {# 实现分页标签的代码 #} {# 这里使用 bootstrap 渲染页面 #}
<div id="pages" class="text-center" >
<nav>
<ul class="pagination">
<li class="step-links">
{% if books.has_previous %}
<a class='active' href="?page={{%20books.previous_page_number%20}}">上一页</a>
{% endif %}
<span class="current">
Page {{ books.number }} of {{ books.paginator.num_pages }}</span>
{% if books.has_next %}
<a class='active' href="?page={{%20books.next_page_number%20}}">下一页</a>
{% endif %}
</li>
</ul>
</nav>
</div>
</body>
</html>
3.3 运行结果我在urls.py中配置了应用程序当前的访问路径为paginator/。于是用浏览器访问http://127.0.0.1:8000/paginator/,查看访问结果如下
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。