简单讲解Django分页Paginator和Page的用法
在 Django 中实现分页功能非常简单。因为 Django 已经内置了两个处理分类的类。分别 是 Paginator 和 Page 。 Paginator 用来管理整个分类的一些属性, Page 用来管理当前这个分 页的一些属性。通过这两个类,就可以轻松的实现分页效果。以下对这两个类进行讲解。
Paginator 类
Paginator 是用来控制整个分页的逻辑的。比如总共有多少页,页码区间等.
创建Paginator对象:
class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True) ,其中的参 数解释如下:
object_list (必选):列表,元组, QuerySet 或者是任何可以做切片操作的对象。会将这个里面的对象进行分页。 QuerySet带有count() or __len__()方法的列表,元组或其他可分片对象。为了保持一致的分页,QuerySet应该对s进行排序,例如在模型中使用order_by() 子句或缺省值ordering。
per_page (必选):分页中,一页展示多少条数据,包含在页面上的最大项目数 ,不包括 orphans。
orphans (可选):用来控制最后一页元素的个人如果少于 orphans 指定的个数的时候,就会将多余 的添加到上一页中。
allow_empty_first_page(可选) :如果 object_list 没有任何数据,并且这个参数设置为 True , 那么就会抛出 EmptyPage 异常。
常用属性和方法:
Paginator.page(number) :获取 number 这页的 Page 对象。
count :传进来的 object_list 总共的数量。
num_pages :总共的页数。
page_range :页码的列表。比如 [1,2,3,4]
Page 类:
得到Page对象:Paginator.page()
使用Page类构造对象生成Page对象
class Page(object_list, number, paginator)
常用属性和方法:
has_next() :是否还有下一页。
has_previous() :是否还有上一页。
next_page_number() :下一页的页码。
previous_page_number() :上一页的页码。
object_list :在当前这页上的对象列表。
number :当前的页码。
paginator :获取 Paginator 对象。
例一:
#views.py from django.shortcuts import render_to_response from django.core.paginator import Paginator def classify(request): """ 注意:objects可以为:列表/元组,Django QuerySet或任何其他对象 """ # 获取所有的对象的列表 objects = goods.objects.all() # objects = ['john', 'paul', 'george', 'ringo'] # 把对象分成 2 个一页 paginator = Paginator(objects, 2) # 获取分页器里面的Page总数 paginator.count # -> 4 # 获取Page的数量 paginator.num_pages # -> 2 # 获取Page数目的范围(返回一个range_iterator对象) paginator.page_range # -> range(1, 3) # 获得第一/二页的Page对象 # <Page 1 of 2> # 返回Page具有给定从1开始的索引的对象。InvalidPage如果给定页码不存在则引发 。 page1 = paginator.page(1) # <Page 1 of 2>django2以上新增功能:返回Page具有给定的基于1的索引的对象 #同时处理超出范围和无效页码(超出范围不会报错,默认返回最后一个Page对象) page2 = paginator.get_page(2) # 获得第一个Page对象中的所有内容 page1.object_list # -> ['john', 'paul'] # 判断下一个Page对象是否存在 page2.has_next() # -> False # 判断上一个Page对象是否存在 page1.has_previous() #-> False # 判断是否还有其他Page对象 page2.has_other_pages() # True # 返回下一个Page对象的索引。如果没有,则触发EmptyPage page2.next_page_number() # 报错 # 返回上一个Page对象的索引。如果没有,则触发EmptyPage page2.previous_page_number() # 1 # 返回第一个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1) page1.start_index() # 1 # 返回第二个Page对象中的第一个元素的索引值(原对象的第一个元素的位置为1) page2.start_index() # 3 # 返回第二个Page对象里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1) page1.end_index() # 2 # 返回第二个分页器里面的第一个对象的最后一个元素位置(原对象的第一个元素的位置为1) page2.end_index() # 4 # 获取当前页码 current_page_num = page1.number return render_to_response('index.html')
例二:
要求不复杂的话,直接使用以下的的设置即可,如有其它需求,可根据需求自定义。
使用方法:
1、导入分页所需的类
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
2、对需要的数据进行处理
def index(request): news = Article.objects.all().order_by('-id')#把需要分页的数据实例化 page = request.GET.get('page')# 获取分页数 paginator = Paginator(news, 10)#设置一页显示多少条数据(news为要分页的数据) try: news = paginator.page(page) # 获取当前页码的记录 except PageNotAnInteger: news = paginator.page(1) # 如果用户输入的页码不是整数时,显示第1页的内容 except EmptyPage: news = paginator.page(paginator.num_pages) # 如果用户输入的页数不在系统的页码列表中时,显示最后一页的内容 return render(request, 'index.html', locals())
3、前端分页效果:
<div class="pages"> <ul> {# 首页按钮,固定page=1 #} <li><a href='?page=1'>首页</a></li> {# 如果上一页还有数据,那么让其可继续点击进入上一页 #} {% if news.has_previous %} <li><a href="?page={{ news.previous_page_number }}" data-ey_fc35fdc="html" data-tmp="1">上一页</a> </li> {# 如果上一页没有数据了,那么不让做任何操作 #} {% else %} {% endif %} {# 由后端经逻辑判断后的page_range页数列表进行迭代 #} {% for num in news.paginator.page_range %} {# 如果循环的页码与当前查看的页码相等,那么就让其高亮显示 #} {% if num == news.number %} <li class="thisclass"><a>{{ num }}</a></li> {% else %} <li><a href="?page={{ num }}" data-ey_fc35fdc="html" data-tmp="1">{{ num }}</a></li> {% endif %} {% endfor %} {# 如果当前页还有下一页,那么让其可以点击进入下一页 #} {% if news.has_next %} <li><a href="?page={{ news.next_page_number }}" data-ey_fc35fdc="html" data-tmp="1">下一页</a></li> {% endif %} {# 跳转到尾页,让page参数直接等于总页数 #} <li><a href='?page={{ paginator.num_pages }}'>尾页</a></li> </ul> </div>
效果如图:
更多资料,可以查看官方文档。
https://docs.djangoproject.com/zh-hans/4.0/ref/paginator/#django.core.paginator.Paginator
文章评论 0