我们前面完成的客户纪录展示,只有4条,如果有上百条就不能在1页中全部展示了,那样是不人性化的.另外一次性取出来,数据量也比较大.
假如现在有95条数据,我们想实现一个每页展示20条,那就分为5页.假如我们实现了,那么前端每一次请求就需要给后台提供参数了.这个参数就是告诉views里的视图函数我取第几页.
需求分析:
95条,每页20条
第一次请求 返回20条,并且后端返回当前返回是第几页 ,所以第一次返回是1
点击下一页 1+1=2 ,把2传给后端,后端拿到后在把第二页的内容返回给前端,并且把当前返回的页这里是2,返回给前端.
按照这个需求,我们自己写,也是很容易实现的(这是对于老手),但是这个分页功能属于一个常用而且通用的功能,Django就提供了Paginator模块来实现后台分页的功能.
Django提供的是后台分页的功能,前端要使用bootstrap中的分页示例代码
我们先看看Django中处理分页的模块都有哪些方法:
$python3.5 manage.py shell
>>> from django.core.paginator import Paginator # 导入Paginator
>>> objects = ['john','paul','george','ringo']
>>> p = Paginator(objects,2) # 生成一个分页的实例,两个参数(objects是列表,2代表的是每2个元素分成一页.)
那我们来看看p这个实例有几个方法
>>> p.count # 查看有多少个元素
4
>>> p.num_pages # 查看总共有几页
2
>>> type(p.page_range)
<class 'range'>
>>> p.page_range # 当我们想循环每一页时就需要用到这个. for num in p.page_range:page = p.page(1)
range(1, 3)
>>> page1 = p.page(1) # p.page(num) 取第几页
>>> page1 # page1 显示这事第几页
<Page 1 of 2>
>>> page1.object_list # 显示页里面的元素,以列表的方式
['john', 'paul']
>>> p.object_list # 显示p实例里有多少个元素
['john', 'paul', 'george', 'ringo']
>>> page2 = p.page(2) # 第二页
>>> page2.object_list # 查看第二页有多少个元素
['george', 'ringo']
>>> page2.has_next() # 查看当前页是不是有下一页,如果有返回True,如果没有Flase
False
>>> page2.has_previous() # 查看当前页是不是有上一页,如果有返回True,如果没有返回False
True
>>> page2.has_other_pages() # 查看除了当前页之外还有没有其它页,如果有返回True,如果没有返回False
True
>>> page1.next_page_number() # 查看当前页的下一页的页码
2
>>> page2.next_page_number() # 查看当前页的下一页的页码,如果没有则报错
Traceback (most recent call last):
......
django.core.paginator.EmptyPage: That page contains no results
>>> page2.previous_page_number() # 查看当前页的上一页的页码.
1
>>> page1.previous_page_number() # 查看当前页的上一页的页码,如果没有则报错
Traceback (most recent call last):
......
django.core.paginator.EmptyPage: That page number is less than 1
>>> page1.start_index() # 查看当前页中,第一个元素在总列表的索引值
1
>>> page2.start_index() # 查看当前页中,第一个元素在总列表的索引值
3
>>> page1.end_index() # 查看当前页中,最后一个元素在总列表的索引值
2
>>> page2.end_index() # 查看当前页中,最后一个元素在总列表的索引值
4
>>> p.page(0) # 当所取页超出p.page_range()范围,就会报错了
Traceback (most recent call last):
...
django.core.paginator.EmptyPage: That page number is less than 1
Django分页的官网
https://docs.djangoproject.com/en/1.9/topics/pagination/
我们来看下后台中到底如何使用,我们从django中查看有详细的示例代码.按照这些示例代码完全没问题

我们在crm/views.py文件中的代码如下:
1 from django.shortcuts import render
2 from crm import models
3 from django.core.paginator import import Paginator,EmptyPage,PageNotAnInteger # 两个异常
4 # Create your views here.
5
6 def dashboard(request):
7 return render(request,'crm/dashboard.html')
8 def customers(request):
9 customer_list = models.Customer.objects.all()
10 paginator = Paginator(customer_list,2) # 每页显示2条纪录
11 page = request.GET.get('page') #获取客户端请求传来的页码
12 try:
13 customer_list = paginator.page(page) # 返回用户请求的页码对象
14 except PageNotAnInteger: # 如果请求中的page不是数字,也就是为空的情况下
15 customer_list = paginator.page(1)
16 except EmptyPage:
17 # 如果请求的页码数超出paginator.page_range(),则返回paginator页码对象的最后一页
18 customer_list = paginator.page(paginator.num_pages)
19
20 return render(request,'crm/customers.html',{'customer_list':customer_list})
需要注意的是:通过costomer_list = paginator.page(数字)获得的对象,是paginator分页实例,但是当我们对这个对象进行for循环时,遍历出来的还是里面的元素.
所以我们可以在html模版中代码依然是直接对 custormer_list 进行for循环,我一开始还以为要用{% for custormer in customer_list.object_list %}呢,结果在官网的html示例代码中是{% for custormer in customer_list %}
我试了下,两个都可以使用
然后我们在看下官网上给我们指引的需要在html模版文件中需要做的改动:

更改templates/crm/customer.html文件
![]()
1 from django.shortcuts import render
2 from crm import models
3 from django.core.paginator import import Paginator,EmptyPage,PageNotAnInteger # 两个异常
4 # Create your views here.
5
6 def dashboard(request):
7 return render(request,'crm/dashboard.html')
8 def customers(request):
9 customer_list = models.Customer.objects.all()
10 paginator = Paginator(customer_list,2) # 每页显示2条纪录
11
12 page = request.GET.get('page') #获取客户端请求传来的页码
13
14 try:
15 customer_list = paginator.page(page) # 返回用户请求的页码对象
16 except PageNotAnInteger: # 如果请求中的page不是数字,也就是为空的情况下
17 customer_list = paginator.page(1)
18 except EmptyPage:
19 # 如果请求的页码数超出paginator.page_range(),则返回paginator页码对象的最后一页
20 customer_list = paginator.page(paginator.num_pages)
21
22 return render(request,'crm/customers.html',{'customer_list':customer_list})
customer.html