day20-自定义分页2
一、前言
之前我们只是稍微学习了一下,但是前面的功能还不完善,比如说之前我们写的,显示全部的页数,但是我们只想显示11页,还有就是第1页和最后一页是没有办法再延伸的,这个我们都是要考虑的,今天我们就来看看,一个完美的分页功能是如何实现的?
二、实现的原理图
三、后台代码
说明:上面的逻辑图是如何获取start_index和end_index,所以整个的代码实现如下图:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 li = list() 2 for i in range(509): 3 li.append(i) 4 5 def user_list(request): 6 current_page = request.GET.get("p",1) 7 current_page = int(current_page) 8 #获取当前页的数据 9 per_page_count = 10 10 start = (current_page-1) * per_page_count 11 end = current_page * per_page_count 12 data = li[start:end] 13 #获取总页数 14 all_count = len(li) 15 total_count,y = divmod(all_count,per_page_count) #返回商和余数,商是页数,余数是是否有最后一页 16 if y: 17 total_count += 1 18 page_num = 11 19 page_list = list() 20 #获取start_index和end_index 21 if total_count < page_num: 22 start_index = 1 23 end_index = total_count + 1 24 else: 25 if current_page <= (page_num + 1)/2: 26 start_index = 1 27 end_index = page_num + 1 28 else: 29 start_index = current_page - (page_num - 1)/2 30 end_index = current_page + (page_num + 1)/2 31 if(current_page + (page_num - 1)/2) > total_count: 32 end_index = total_count + 1 33 start_index = total_count - page_num + 1 34 #判断是否是第一页 35 if current_page == 1: 36 prev = '<a class="page" href="javascript:void(0);">上一页</a>' 37 else: 38 prev = '<a class="page" href="/user_list/?p=%s">上一页</a>'%(current_page-1,) 39 page_list.append(prev) 40 #利用后端往前端放 41 for i in range(int(start_index),int(end_index)): 42 if i == current_page: #判断是否是当前页 43 temp = '<a class="page active" href="/user_list/?p=%s">%s</a>'%(i,i) 44 else: 45 temp = '<a class="page" href="/user_list/?p=%s">%s</a>'%(i,i) 46 page_list.append(temp) 47 #判断是否是最后一页 48 if current_page == total_count: 49 nex = '<a class="page" href="javascript:void(0);">下一页</a>' #表示什么也不干,也可以用是href='#' 50 else: 51 nex = '<a class="page" href="/user_list/?p=%s">下一页</a>'%(current_page+1) 52 page_list.append(nex) 53 #这个是跳转到某个页面,这边也可以在前端写 54 jump = ''' 55 <input type="text"/><a onclick='jumpTo(this,"/user_list/?p=");' id='ii1'>GO</a> 56 <script> 57 function jumpTo(ths,base){ 58 var val = ths.previousSibling.value; 59 location.href = base + val; 60 } 61 </script> 62 ''' 63 page_list.append(jump) 64 page_str = ''.join(page_list) #拼凑 65 from django.utils.safestring import mark_safe 66 page_str = mark_safe(page_str) #防止xss攻击,否则前端不识别html 67 return render(request,'user_list.html',{'li':data,'page_str':page_str})
注意了:
'<a class="page" href="javascript:void(0);">下一页</a>' 中href="javascript:void(0);"表示什么都没有干,相当于href="#"
四、分页封装成类
4.1、分页功能封装
说明:我们在项目下创建一个文件夹,叫utils工具文件夹,并且在这个下面创建一个pagination.py文件,在文件中创建Page类,分页封装内容如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 from django.utils.safestring import mark_safe 2 3 class Page(object): 4 5 def __init__(self,current_page,data_count,per_page_count=10,pager_num=7): 6 self.current_page = current_page 7 self.data_count = data_count 8 self.per_page_count = per_page_count 9 self.pager_num = pager_num 10 11 #通过self.start 直接获取return的值 12 @property 13 def start(self): 14 return (self.current_page-1) * self.per_page_count 15 #通过self.end 直接获取return的值 16 17 @property 18 def end(self): 19 return self.current_page * self.per_page_count 20 #通过self.total_count 直接获取v值 21 @property 22 def total_count(self): 23 v,y = divmod(self.data_count,self.per_page_count) 24 if y: 25 v += 1 26 return v 27 28 29 def page_str(self,base_url): 30 page_list = list() 31 if self.total_count < self.pager_num: 32 start_index = 1 33 end_index = self.total_count + 1 34 else: 35 if self.current_page <= (self.pager_num + 1)/2: 36 start_index = 1 37 end_index = self.pager_num + 1 38 else: 39 start_index = self.current_page - (self.pager_num - 1)/2 40 end_index = self.current_page + (self.pager_num + 1)/2 41 if(self.current_page + (self.pager_num - 1)/2) > self.total_count: 42 end_index = self.total_count + 1 43 start_index = self.total_count - self.pager_num + 1 44 #判断是否是第一页 45 if self.current_page == 1: 46 prev = '<a class="page" href="javascript:void(0);">上一页</a>' 47 else: 48 prev = '<a class="page" href="%s?p=%s">上一页</a>'%(base_url,self.current_page-1,) 49 page_list.append(prev) 50 #利用后端往前端放 51 for i in range(int(start_index),int(end_index)): 52 if i == self.current_page: #判断是否是当前页 53 temp = '<a class="page active" href="%s?p=%s">%s</a>'%(base_url,i,i) 54 else: 55 temp = '<a class="page" href="%s?p=%s">%s</a>'%(base_url,i,i) 56 page_list.append(temp) 57 #判断是否是最后一页 58 if self.current_page == self.total_count: 59 nex = '<a class="page" href="javascript:void(0);">下一页</a>' #表示什么也不干,也可以用是href='#' 60 else: 61 nex = '<a class="page" href="%s?p=%s">下一页</a>'%(base_url,self.current_page+1) 62 page_list.append(nex) 63 64 jump = ''' 65 <input type="text"/><a onclick='jumpTo(this,"%s?p=");' id='ii1'>GO</a> 66 <script> 67 function jumpTo(ths,base){ 68 var val = ths.previousSibling.value; 69 location.href = base + val; 70 } 71 </script> 72 '''%(base_url,) 73 page_list.append(jump) 74 page_str = ''.join(page_list) #拼凑 75 page_str = mark_safe(page_str) #防止xss攻击,否则前端不识别html 76 77 return page_str
如图:
4.2、view.py代码的引用
说明:在函数user_list中导入该类并且,使用该类的分页功能
from utils import pagination li = list() for i in range(509): li.append(i) def user_list(request): current_page = request.GET.get("p",1) current_page = int(current_page) #获取对象 page_obj = pagination.Page(current_page,len(li),pager_num=11) ##获取当前页的数据 data = li[page_obj.start:page_obj.end] #显示的页数 page_str = page_obj.page_str("/user_list/") return render(request,'user_list.html',{'li':data,'page_str':page_str})
如图: