自己编写面向对象的分页
在项目中,经常需要分页,Django框架里自带了分页
Paginator,Page
里面有这些参数:
我随便拿一个视图来看下:
1 def index(request): 2 """ 3 django 本身携带分页 4 :param request: 5 :return: 6 """ 7 # for i in range(300): 8 # name = "root" + str(i) 9 # models.UserInfo.objects.create(name=name,age=18,ut_id=1) 10 11 12 current_page = request.GET.get('page') 13 14 user_list = models.UserInfo.objects.all() 15 paginator = Paginator(user_list,10) 16 # per_page: 每页显示条目数量 17 # count: 数据总个数 18 # num_pages:总页数 19 # page_range:总页数的索引范围,如: (1,10),(1,200) 20 # page: page对象 21 try: 22 posts = paginator.page(current_page) 23 except PageNotAnInteger as e: 24 posts = paginator.page(1) 25 except EmptyPage as e: 26 posts = paginator.page(1) 27 # has_next 是否有下一页 28 # next_page_number 下一页页码 29 # has_previous 是否有上一页 30 # previous_page_number 上一页页码 31 # object_list 分页之后的数据列表 32 # number 当前页 33 # paginator paginator对象 34 return render(request,'index.html',{'posts':posts})
由于django自带框架有局限性,为了达到要求需要二次开发,有点繁琐,
但是我们自己为什么不自己搞一个面向对象的分页呢,自己还好用,随便用。
面向对象的分页代服务端代码:我把他放到自己建立的utils(意思是实用工具)文件夹下,命名为pageser.py
class Page1(object): def __init__(self,cur_page,all_count,per_page,show_page,base_url): # 控制传输进入的页码是负数进行处理为首页 try: self.cur_page = int(cur_page) except Exception as e: self.cur_page = 1 # 计算实际的总页数,页面因为实际的总页数和默认每页显示的页码存在有趣的关系 print("all_count:",all_count) a,b = divmod(all_count,per_page) print("a:",a,"b:",b) if b: a = a+1
self.real_page = a
else: self.real_page = a #print("self.real_page:",self.real_page) # 显示每页输出的记录条数 self.per_page = per_page # 默认显示的每页页码数目 self.show_page = show_page # 点击页码的a标签的href中的基本路径 self.base_url = base_url def start(self): ''' 数据库根据当前页数取数据的开始位置 :return: ''' return (self.cur_page - 1) * self.per_page def stop(self): ''' 数据库根据当前页数取数据的结束位置 :return: ''' return self.cur_page * self.per_page def pager(self): ''' 返回充满页码的列表 :return: ''' page_list = [] half = int((self.show_page-1)/2) # 如果实际页码数(比如实际数据只有3页) < 默认页码数(比如默认每页显示11个页码) if self.real_page < self.show_page: start = 1 stop = self.real_page +1 # 如果实际页码数(比如实际数据只有3页) > 默认页码数(比如默认每页显示11个页码) else: # 如果当前页 < half,就要永远显示1到默认页码数 if self.cur_page <= half: start = 1 stop = self.show_page +1 # 如果当前页 > half,就要当前页码的前后各half个页码 else: # 但是当当前页+half > 总页码时候,不能展示后面没有数据的页码 if self.cur_page + half > self.real_page: start = self.real_page - self.show_page +1 stop = self.real_page +1 else: start = self.cur_page - half stop = self.cur_page + half +1 # 上一页的处理 if self.cur_page <=1: prev = "<li><a href='#'>上一页</a></li>" else: prev = "<li><a href='%s?page=%s'>上一页</a></li>" % (self.base_url, self.cur_page - 1,) page_list.append(prev) # 首页处理 if self.cur_page > half+1: first = "<li style='display:inline;'><a href='%s?page=1'>首页</a></li>"%(self.base_url,) else: first = "<li style='display:none;'><a href='#'>首页</a></li>" page_list.insert(1,first) # 中间生成的页码的处理 for i in range(start,stop): # 如果是当前的页码,样式要不一样,class="active" 是bootstrap的选中样式 if i == self.cur_page: tmp = "<li class='active'><a href='%s?page=%s'>%s</a></li>"%(self.base_url,i,i,) else: tmp = "<li ><a href='%s?page=%s'>%s</a></li>"%(self.base_url,i,i,) page_list.append(tmp) # 终页处理 if self.cur_page < (self.real_page - half): last = "<li style='display:inline;'><a href='%s?page=%s'>终页</a></li>" % (self.base_url,self.real_page) else: last = "<li style='display:none;'><a href='#'>终页</a></li>" page_list.insert(self.show_page+2,last) # 下一页的处理 if self.cur_page >= self.real_page: nextp = "<li><a href='#'>下一页</a></li>" else: nextp = "<li><a href='%s?page=%s'>下一页</a></li>" % (self.base_url, self.cur_page + 1,) page_list.append(nextp) # 综合以上其实每次点击当前页码,就会重新渲染,连贯起来就是分页 return ''.join(page_list)
而路由系统的写法是:
1 urlpatterns = [ 2 3 url(r'^customxwk.html$', views.customxwk), 4 5 ]
在views.py 的视图中的写法是:
1 导入类 2 from utils.pageser import Page1 3 def customxwk(request): 4 5 # 数据库中塞300条数据,执行一次注释掉 6 # for i in range(300): 7 # name = "root" + str(i) 8 # models.UserInfo.objects.create(name=name,age=18,ut_id=1)
至于数据库中的userinfo 表中,有id,name,age,ut_id四列,ut_id是关联usertype 的外键
9 10 11 # 统计数据库某表条数 12 all_count = models.UserInfo.objects.all().count() 13 print("customxwk all_count:",all_count) 14 15 # 类传入参数实例化 16 page1 = Page1(request.GET.get('page'),all_count,10,11,'/customxwk.html') 17 18 # 根据页码取当页数据 19 user_list = models.UserInfo.objects.all()[page1.start():page1.stop()] 20 21 # models.UserInfo.objects.all().delete() 22 # 返回给请求页,将数据放到占位符中 23 24 return render(request,'customxwk.html',{'user_list':user_list,'page1':page1})
在前端模板的是,利用bootstrap的样式:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" /> 7 </head> 8 <body> 9 10 11 <h1>User List</h1> 12 13 <ul> 14 {% for row in user_list %} 15 <li>{{ row.name }}</li> 16 {% endfor %} 17 </ul> 18 19 20 21 <nav aria-label="Page navigation"> 22 <ul class="pagination"> 23 {{ page1.pager|safe }} 24 </ul> 25 </nav> 26 27 28 </body> 29 </html>
到这里,就结束了,来看看效果:
开始没有首页这个按钮,只有终页按钮
在末尾,终页消失,首页出现:
在中间,首页,终页都出现,并且上下页也都是可以实现的,这样就OK了。
就这样了,需要就把这个copy过去,用起来很方便。