crm03 分页
一、Django的分页器(paginator)
from django.db import models # Create your models here. class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() def __str__(self):return self.title
paginator类的基本属性与方法
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) #数据总数 count: 100 print("num_pages:",paginator.num_pages) #总页数 num_pages: 10 print("page_range:",paginator.page_range) #页码的列表eg:100条数据 如果设置每页显示10条 page_range: range(1, 11); 如果设置每页显示5条 page_range: range(1, 21); page1=paginator.page(1) #第1页的page对象 print(page1) #<Page 1 of 10> for i in page1: #遍历第1页的所有数据对象 print(i)# book_1 # book_2 # book_3 # book_4 # book_5 # book_6 # book_7 # book_8 # book_9 # book_10 print(page1.object_list) #第1页的所有数据对象 #[<Book: book_1>, <Book: book_2>, <Book: book_3>, <Book: book_4>, <Book: book_5>, <Book: book_6>, <Book: book_7>, <Book: book_8>, <Book: book_9>, <Book: book_10>] page2=paginator.page(2) print(page2.has_next()) #是否有下一页 True print(page2.next_page_number()) #下一页的页码 3 print(page2.has_previous()) #是否有上一页 True print(page2.previous_page_number()) #上一页的页码 1 # 抛错 #page=paginator.page(12) # error:EmptyPage #page=paginator.page("z") # error:PageNotAnInteger # # ''' return HttpResponse('okok')
小栗子
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): # 抛错 #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,"index0.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </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="/index0/?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="/index0/?page={{ num }}">{{ num }}</a></li> {% else %} <li class="item"><a href="/index0/?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if book_list.has_next %} <li class="next"><a href="/index0/?page={{ book_list.next_page_number }}">下一页</a></li> {% else %} <li class="next disabled"><a href="#">下一页</a></li> {% endif %} </ul> </div> </body> </html>
二、扩展
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): book_list = Book.objects.all() paginator = Paginator(book_list, 5) try: current_page=int(request.GET.get("page",1)) page = paginator.page(current_page) if paginator.num_pages > 11: if current_page - 5 < 1: pageRange = range(1, 12) elif current_page + 5 > paginator.num_pages: pageRange = range(paginator.num_pages - 10, paginator.num_pages + 1) #range()取不到尾 所以+1 else: pageRange = range(current_page - 5, current_page + 6) else: pageRange = paginator.page_range #总页数小于等于11 用它本身的range except EmptyPage as e: page = paginator.page(1) return render(request,"index.html",locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </head> <body> <ul> {% for book in page %} <li>{{ book }}</li> {% endfor %} </ul> <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">上一页</span> </a> </li> {% for num in pageRange %} {% if current_page == num %} <li class="active"><a href="?page={{ num }}">{{ num }}</a></li> {% else %} <li><a href="?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} {% if page.has_next %} <li> <a href="?page={{ page.next_page_number }}" aria-label="Next"> <span aria-hidden="true">下一页</span> </a> </li> {% else %} <li class="disabled"> <a href="#" aria-label="Next"> <span aria-hidden="true">下一页</span> </a> </li> {% endif %} </ul> </nav> </body> </html>
三、自定义分页器
class Pagination(object): def __init__(self,request,current_page,all_data,per_page_num=2,max_page_count=11): """ 封装分页相关数据 :param current_page: 当前页 :param all_count: 分页数据中的数据总条数 :param per_page_num: 每页显示的数据条数 :param max_page_count: 最多显示的页码个数 """ try: current_page = int(current_page) except Exception as e: current_page = 1 if current_page <1: current_page = 1 self.current_page = current_page self.all_count = len(all_data) self.per_page_num = per_page_num # 总页码 all_pager, tmp = divmod(self.all_count, per_page_num)# 除法 商与余数 if tmp: #余数存在 all_pager 要加1 all_pager += 1 self.all_pager = all_pager self.max_page_count = max_page_count self.max_page_count_half = int((max_page_count - 1) / 2) # self.request=request # import copy self.params=copy.deepcopy(self.request.GET)#self.request.GET该字典不能增加和修改,所以copy一个 print(self.params.urlencode()) #eg:字符串:page=9&a=1 ''' all_count=100 per_page_num =10 current_page start end 1 0 10 2 10 20 3 20 30 all_count=100 per_page_num =8 current_page start end 1 0 8 2 8 16 3 16 24 表达式: start= (current_page-1)*per_page_num end =current_page* per_page_num ''' @property def start(self): return (self.current_page - 1) * self.per_page_num #当前页的第一条数据 @property def end(self): return self.current_page * self.per_page_num ##当前页的最后一条数据 def page_html(self): # 如果总页码 < 11个: if self.all_pager <= self.max_page_count: pageRange=range(1, self.all_pager + 1) #因为range顾首不顾尾 # 总页码 > 11 else: # 当前页如果小于页面上最多显示(11-1)/2个页码 if self.current_page <= self.max_page_count_half: pageRange=range(1,self.max_page_count + 1) #eg:当前页码为3 1,2, 3 4,5,6,7,8,9,10,11 因为self.max_page_count =11 self.max_page_count_half=5 # 当前页大于5 else: # 页码翻到最后 if (self.current_page + self.max_page_count_half) > self.all_pager: pageRange=range(self.all_pager-self.max_page_count+1,self.all_pager + 1)#eg:self.current_page当前为16,self.all_pager总页数为20 11-20 else: pageRange=range(self.current_page - self.max_page_count_half,self.current_page + self.max_page_count_half + 1)#eg:self.current_page当前为10 range(5,16) # 构建分页页码的html page_html_list = [] self.params["page"]=1 #修改拷贝的self.request.GET该字典page键值 first_page = '<nav aria-label="Page navigation"><ul class="pagination"> <li><a href="?%s">首页</a></li>' % (self.params.urlencode(),) page_html_list.append(first_page) self.params["page"] = self.current_page - 1 # #修改拷贝的self.request.GET该字典page键值 if self.current_page <= 1: prev_page = '<li class="disabled"><a href="#">上一页</a></li>' #如果当前页码小于等于1 上一页按钮禁止点击 else: prev_page = '<li><a href="?%s">上一页</a></li>' % (self.params.urlencode(),) page_html_list.append(prev_page) # self.params: ["page":9,"a":1,"b":2] for i in pageRange: self.params["page"]=i # #修改拷贝的self.request.GET该字典page键值 if i == self.current_page: temp = '<li class="active"><a href="?%s">%s</a></li>' % (self.params.urlencode(), i,) #选择的当前按钮颜色加深 else: temp = '<li><a href="?%s">%s</a></li>' % (self.params.urlencode(),i,) page_html_list.append(temp) self.params["page"] = self.current_page + 1 # #修改拷贝的self.request.GET该字典page键值 if self.current_page >= self.all_pager: next_page = '<li class="disabled"><a href="#">下一页</a></li>' #如果当前页码大于等于总页数 下一页按钮禁止点击 else: next_page = '<li><a href="?%s">下一页</a></li>' % (self.params.urlencode(),) page_html_list.append(next_page) self.params["page"]=self.all_pager last_page = '<li><a href="?%s">尾页</a></li> </ul></nav>' % (self.params.urlencode()) page_html_list.append(last_page) return ''.join(page_html_list) def index(request): ''' # request.GET["xxx"]="yyy" # This QueryDict instance is immutable from django.http.request import QueryDict import copy params=copy.deepcopy(request.GET) print(params) # params["xxx"]="yyy" print(params) # <QueryDict: {'page': ['9'], 'a': ['1'], 'xxx': ['yyy']}> print(params.urlencode()) # QueryDict------>字符串:page=9&a=1 :param request: :return: ''' print(request.GET) # eg:<QueryDict: {'page': ['9'], 'a': ['1']}> print(type(request.GET)) #eg: django.http.request.QueryDict book_list = Book.objects.all() current_page = int(request.GET.get("page", 1)) pagination=Pagination(request,current_page,book_list,per_page_num=5) book_list=book_list[pagination.start:pagination.end] return render(request,"index2.html",locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <!-- 最新版本的 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"> </head> <body> <ul> {% for book in book_list %} <li>{{ book }}</li> {% endfor %} </ul> <div> {{ pagination.page_html|safe }} </div> </body> </html>