django分页器
参考博文:https://www.cnblogs.com/yuanchenqi/articles/9036515.html
精华总结
1,批量导入: book_list=[] for i in range(100): book=Book(title="book_%s"%i,price=i*i) book_list.append(book) Book.objects.bulk_create(book_list) 2,分页器: paginator=Paginator(book_list,3) print("count:",paginator.count) #数据总数 print("num_pages",paginator.num_pages) #总页数 print("page_range",paginator.page_range) #页码的列表 3,当前页 current_page_num=int(request.GET.get("page",1)) # 1代表默认第一页 4,页面超出范围 except EmptyPage as e: current_page=paginator.page(1) # 显示第一页 5,下面点击数字 {% for item in page_range %} li><a href="?page={{ item }}">{{ item }}</a></li> # ?page={{ item }} 跳转当前页面 {% endfor %} 6,当前页码变色 {% if current_page_num == item %} <li class="active"><a href="?page={{ item }}">{{ item }}</a></li> {% else %} <li><a href="?page={{ item }}">{{ item }}</a></li> {% endif %} 7,上一页 页码: <li><a href="?page={{ current_page_num|add:-1 }}" aria-label="Previous"><span aria-hidden="true">上一页 分页对象: <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一页 8,上下页 print(page2.has_next()) #是否有下一页 print(page2.next_page_number()) #下一页的页码 print(page2.has_previous()) #是否有上一页 print(page2.previous_page_number()) #上一页的页码 9,当前页有无下一页 {% if current_page.has_previous %} <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% endif %} 10,显示11个页码 view代码: if paginator.num_pages>11: # 页码数超过11 if current_page_num-5<1: # 小于1页 page_range=range(1,12) elif current_page_num+5>paginator.num_pages: # 大于最后一页 page_range=range(paginator.num_pages-10,paginator.num_pages+1) else: page_range=range(current_page_num-5,current_page_num+6) # 当前页码,左边右边都是5页 else: page_range=paginator.page_range 页面代码: {% for item in page_range %}
精简示例
页面模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <ul> {% for book in current_page %} <li>{{ book.title }}:{{ book.price }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> {% if current_page.has_previous %} <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% else %} <li class="disabled"><a href="" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% endif %} {% for item in page_range %} {% if current_page_num == item %} <li class="active"><a href="?page={{ item }}">{{ item }}</a></li> {% else %} <li><a href="?page={{ item }}">{{ item }}</a></li> {% endif %} {% endfor %} {% if current_page.has_next %} <li><a href="?page={{ current_page.next_page_number }}" aria-label="Next"><span aria-hidden="true">下一页</span></a> {% else %} <li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">下一页</span></a> {% endif %} </li> </ul> </nav> </body> </html>
视图代码:
from django.core.paginator import Paginator, EmptyPage def index(request): # book_list = [] # for i in range(100): # book = BookPage(title="book_%s" % i, price=i * i) # book_list.append(book) # # BookPage.objects.bulk_create(book_list) # return HttpResponse("ok") book_list = BookPage.objects.all() # 分页器 paginator = Paginator(book_list, 3) print("count:", paginator.count) # 数据总数 print("num_pages", paginator.num_pages) # 总页数 print("page_range", paginator.page_range) # 页码的列表 current_page_num = int(request.GET.get("page", 1)) if paginator.num_pages > 11: if current_page_num - 5 < 1: page_range = range(1, 12) elif current_page_num + 5 > paginator.num_pages: page_range = range(paginator.num_pages - 10, paginator.num_pages + 1) else: page_range = range(current_page_num - 5, current_page_num + 6) else: page_range = paginator.page_range try: current_page = paginator.page(current_page_num) # 显示某一页具体数据的两种方式: print("object_list", current_page.object_list) for i in current_page: print(i) except EmptyPage as e: current_page = paginator.page(1) return render(request, "index_page.html", locals())
大佬视图:
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): ''' 批量导入数据: Booklist=[] for i in range(100): Booklist.append(Book(title="book"+str(i),price=30+i*i)) Book.objects.bulk_create(Booklist) ''' ''' 分页器的使用: book_list=Book.objects.all() paginator = Paginator(book_list, 10) print("count:",paginator.count) #数据总数 print("num_pages",paginator.num_pages) #总页数 print("page_range",paginator.page_range) #页码的列表 page1=paginator.page(1) #第1页的page对象 for i in page1: #遍历第1页的所有数据对象 print(i) print(page1.object_list) #第1页的所有数据 page2=paginator.page(2) print(page2.has_next()) #是否有下一页 print(page2.next_page_number()) #下一页的页码 print(page2.has_previous()) #是否有上一页 print(page2.previous_page_number()) #上一页的页码 # 抛错 #page=paginator.page(12) # error:EmptyPage #page=paginator.page("z") # error:PageNotAnInteger ''' book_list=Book.objects.all() paginator = Paginator(book_list, 10) page = request.GET.get('page',1) currentPage=int(page) try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1) except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
模型:
class BookPage(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(decimal_places=2, max_digits=8)
Django的分页器(paginator)
基础知识
构造函数:
Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
必传参数
object_list
一个list,tuple,django的QuerySet,或者拥有``count()``或``__len__()``方法的 可分解对象
per_page
每一页最大的对象个数。
可选参数
orphans
最后一页对象的最少数目,默认为0。 如果想避免最后一页显示太少。则可以使用这个值。 那么最后一页的数据,自动被前移一页。比如总共23个数据。每页显示 10. orphans=3 那么,第一页为10,第二页为13.
allow_empty_first_page
表示首页是否可以为空,如果是 False 而且``object_list`` 为空,那么会触发 EmptyPage 异常。
方法
Paginator.page(number)
根据索引number,返回一个’Page’对象,如果不存在,引起 InvalidPage异常
属性
Paginator.count
所有对象的总数, 尝试通过``object_list.count()``和``object_list.__len__()`` 取得
Paginator.num_pages
总共的页数
Paginator.page_range
页的范围,比如 [1, 2, 3, 4] 。
InvalidPage 异常
当页面不存在或者无效时,会引起``InvalidPage``异常,一般这个异常就够用,如果需要更 详细信息,还有``PageNotAnInteger``,``EmptyPage``可用:
PageNotAnInteger
page() 的参数非整数。
EmptyPage
page(x) ,第x页没数据。
上述两个都是 InvalidPage 的子类。 用一个简单的 except InvalidPage 就可以处理。
Page 类
Page(object_list, number, paginator):
一般不需用户自己构造,通过`Paginator.page` 生成。
方法
Page.has_next()
如果下一页存在,返回True。
Page.has_previous()
如果前一页存在返回 True
Page.has_other_pages()
如果上一页面或者下一页存在,返回``True``
Page.next_page_number()
返回下一页的索引,这个函数比较傻(不管下一页是否存在,都是简单的+1)
Page.previous_page_number()
返回上一页的索引,其他同上
Page.start_index()
返回当前页,第一个对象的索引。
Page.end_index()
道理同上。
属性
Page.object_list
当前页对象列表
Page.number
当前页的索引
Page.paginator
和page相关的分页类
示例代码:
view
from django.shortcuts import render,HttpResponse # Create your views here. from app01.models import * from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger def index(request): ''' 批量导入数据: Booklist=[] for i in range(100): Booklist.append(Book(title="book"+str(i),price=30+i*i)) Book.objects.bulk_create(Booklist) ''' ''' 分页器的使用: book_list=Book.objects.all() paginator = Paginator(book_list, 10) print("count:",paginator.count) #数据总数 print("num_pages",paginator.num_pages) #总页数 print("page_range",paginator.page_range) #页码的列表 page1=paginator.page(1) #第1页的page对象 for i in page1: #遍历第1页的所有数据对象 print(i) print(page1.object_list) #第1页的所有数据 page2=paginator.page(2) print(page2.has_next()) #是否有下一页 print(page2.next_page_number()) #下一页的页码 print(page2.has_previous()) #是否有上一页 print(page2.previous_page_number()) #上一页的页码 # 抛错 #page=paginator.page(12) # error:EmptyPage #page=paginator.page("z") # error:PageNotAnInteger ''' book_list=Book.objects.all() paginator = Paginator(book_list, 10) page = request.GET.get('page',1) currentPage=int(page) try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1) except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
index.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="container"> <h4>分页器</h4> <ul> {% for book in book_list %} <li>{{ book.title }} -----{{ book.price }}</li> {% endfor %} </ul> <ul class="pagination" id="pager"> {% if book_list.has_previous %} <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li> {% else %} <li class="previous disabled"><a href="#">上一页</a></li> {% endif %} {% for num in paginator.page_range %} {% if num == currentPage %} <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% else %} <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if book_list.has_next %} <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li> {% else %} <li class="next disabled"><a href="#">下一页</a></li> {% endif %} </ul> </div> </body> </html>
扩展
def index(request): book_list=Book.objects.all() paginator = Paginator(book_list, 15) page = request.GET.get('page',1) currentPage=int(page) # 如果页数十分多时,换另外一种显示方式 if paginator.num_pages>11: if currentPage-5<1: pageRange=range(1,11) elif currentPage+5>paginator.num_pages: pageRange=range(currentPage-5,paginator.num_pages+1) else: pageRange=range(currentPage-5,currentPage+5) else: pageRange=paginator.page_range try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1) except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",locals())