utils/pager.py
class Pagination(object): def __init__(self, current_page, all_count, base_url, query_params, per_page=30, pager_page_count=11): """ 分页初始化 :param current_page: 当前页码 :param per_page: 每页显示数据条数 :param all_count: 数据库中总条数 :param base_url: 基础URL :param query_params: QueryDict对象,内部含所有当前URL的原条件 :param pager_page_count: 页面上最多显示的页码数量 """ self.base_url = base_url try: self.current_page = int(current_page) if self.current_page <= 0: self.current_page = 1 except Exception as e: self.current_page = 1 query_params = query_params.copy() query_params._mutable = True self.query_params = query_params self.per_page = per_page self.all_count = all_count self.pager_page_count = pager_page_count pager_count, b = divmod(all_count, per_page) if b != 0: pager_count += 1 self.pager_count = pager_count half_pager_page_count = int(pager_page_count / 2) self.half_pager_page_count = half_pager_page_count @property def start(self): """ 数据获取值起始索引 :return: """ return (self.current_page - 1) * self.per_page @property def end(self): """ 数据获取值结束索引 :return: """ return self.current_page * self.per_page def page_html(self): """ 生成HTML页码 :return: """ if self.all_count == 0: return "" # 如果数据总页码pager_count<11 pager_page_count if self.pager_count < self.pager_page_count: pager_start = 1 pager_end = self.pager_count else: # 数据页码已经超过11 # 判断: 如果当前页 <= 5 half_pager_page_count if self.current_page <= self.half_pager_page_count: pager_start = 1 pager_end = self.pager_page_count else: # 如果: 当前页+5 > 总页码 if (self.current_page + self.half_pager_page_count) > self.pager_count: pager_end = self.pager_count pager_start = self.pager_count - self.pager_page_count + 1 else: pager_start = self.current_page - self.half_pager_page_count pager_end = self.current_page + self.half_pager_page_count page_list = [] if self.current_page <= 1: prev = '<li><a href="#">上一页</a></li>' else: self.query_params['page'] = self.current_page - 1 prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode()) page_list.append(prev) for i in range(pager_start, pager_end + 1): self.query_params['page'] = i if self.current_page == i: tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % ( self.base_url, self.query_params.urlencode(), i,) else: tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,) page_list.append(tpl) if self.current_page >= self.pager_count: nex = '<li><a href="#">下一页</a></li>' else: self.query_params['page'] = self.current_page + 1 nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),) page_list.append(nex) if self.all_count: tpl = "<li class='disabled'><a>共%s条数据,页码%s/%s页</a></li>" % ( self.all_count, self.current_page, self.pager_count,) page_list.append(tpl) page_str = "".join(page_list) return page_str
分页组件应用: 1. 在视图函数中 queryset = models.Issues.objects.filter(project_id=project_id) page_object = Pagination( current_page=request.GET.get('page'), all_count=queryset.count(), base_url=request.path_info, query_params=request.GET ) issues_object_list = queryset[page_object.start:page_object.end] context = { 'issues_object_list': issues_object_list, 'page_html': page_object.page_html() } return render(request, 'issues.html', context) 2. 前端 {% for item in issues_object_list %} {{item.xxx}} {% endfor %} <nav aria-label="..."> <ul class="pagination" style="margin-top: 0;"> {{ page_html|safe }} </ul> </nav> """
--------------------旧版--------------------
class PageInfo(object): def __init__(self,current_page,all_count,per_page,base_url,show_page=11): """ :param current_page: :param all_count: 数据库总行数 :param per_page: 每页显示函数 :return: """ try: self.current_page = int(current_page) except Exception as e: self.current_page = 1 self.per_page = per_page a,b = divmod(all_count,per_page) if b: a = a +1 self.all_pager = a self.show_page = show_page self.base_url = base_url def start(self): return (self.current_page-1) * self.per_page def end(self): return self.current_page * self.per_page def pager(self): # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>" # return v page_list = [] half = int((self.show_page-1)/2) # 如果数据总页数 < 11 if self.all_pager < self.show_page: begin = 1 stop = self.all_pager + 1 # 如果数据总页数 > 11 else: # 如果当前页 <=5,永远显示1,11 if self.current_page <= half: begin = 1 stop = self.show_page + 1 else:
# 如果当前页离尾页<=5,永远显示最后的11页 if self.current_page + half > self.all_pager: begin = self.all_pager - self.show_page + 1 stop = self.all_pager + 1 else:
begin = self.current_page - half stop = self.current_page + half + 1 if self.current_page <= 1: prev = "<li><a href='#'>上一页</a></li>" else: prev = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url,self.current_page-1,) page_list.append(prev) for i in range(begin,stop): if i == self.current_page: temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) else: temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,) page_list.append(temp) if self.current_page >= self.all_pager: nex = "<li><a href='#'>下一页</a></li>" else: nex = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url,self.current_page+1,) page_list.append(nex) return ''.join(page_list)
views:
1 from utils.pager import PageInfo 2 def custom(request): 3 all_count = models.UserInfo.objects.all().count() 4 5 page_info = PageInfo(request.GET.get('page'),all_count,10,'/custom.html',11) #返回页码对象 6 user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()] #用户列表 7 8 return render(request,'custom.html',{'user_list':user_list,'page_info':page_info})
html代码:(custom.html)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title></title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> 7 </head> 8 <body> 9 <h1>用户列表</h1> 10 <ul> 11 {% for row in user_list %} 12 <li>{{ row.name }}</li> 13 {% endfor %} 14 </ul> 15 16 <nav aria-label="Page navigation"> 17 <ul class="pagination"> 18 {{ page_info.pager|safe }} 19 </ul> 20 </nav> 21 </body> 22 </html>