使用tornado实现分页,有一下几个重点步骤:
1、分页信息添加:在页面进行信息添加(form表单提交),并自动显示相关内容(模板语言渲染后跳转),
2、限定每页显示的信息数量和显示指定页码的数据
3、使用a标签做页码(href跳转实现分页请求),插入页码脚本代码(需要取消tornado对XSS攻击的自动处理),
4、控制显示的页码数量:当前页及前后5页,
5、模块化,封装成类
目录结构如下:

start.py
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web from templates import home USER_INFO = {} # 路径解析 settings = { "template_path":"views", "static_path":"statics", } # 路由至具体的事件句柄,get方式, application = tornado.web.Application([ (r"/index/(?P<page>\d*)",home.IndexHandler), # page默认值是1 ],**settings) # 开启服务器,监听 if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
home.py(未模块化)
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.web INFO_LIST = [{'name':'<script>alert(123);</script>','pwd':456},{'name':'dongxue','pwd':456}] # 测试数据 for i in range(99): temp = {'name':'dongxue'+str(i),'pwd':str(i)} INFO_LIST.append(temp) # 访问首页 class IndexHandler(tornado.web.RequestHandler): def get(self,page): # 每页显示5条数据 # page是当前页,默认值是1,字符形式 try: page = int(page) except: page = 1 if page < 1: page = 1 start = (page-1)*5 end = page*5 current_list = INFO_LIST[start:end] # 当前显示的数据 all_page,c = divmod(len(INFO_LIST),5) # 计算总页码数 if c > 0: all_page += 1 List_pageCTRL = [] # s\e,指定显示页码的范围 if all_page <= 11: # 总页数不超过11,显示全部页码 s = 0 e = all_page else: # 总页数大于11 if page <= 6: # 且当前页不大于6,显示1-11页码 s = 0 e = 11 else: if page >= (all_page - 5): # 且当前页大于总页数-5,显示最后11页码 s = all_page - 11 e = all_page else: # 否则显示当前页码前5—后5页码 s = page - 6 e = page + 5 for p in range(s,e): # 生成页码控制脚本代码 if p+1 == page: temp = '<a class="active" href="/index/%s">%s</a>'%(p+1,p+1) # 当前页重点显示 else: temp = '<a href="/index/%s">%s</a>'%(p+1,p+1) List_pageCTRL.append(temp) str_pageCtrl = "".join(List_pageCTRL) # 渲染页面并跳转 self.render('home/index.html',info_list = current_list,current_page = page,pageCtrl = str_pageCtrl,) def post(self, page): info_item = {} info_item['name'] = self.get_argument('userName',None) info_item['pwd'] = self.get_argument('passWord',None) INFO_LIST.append(info_item) self.redirect('/index/'+page)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> <script src="{{static_url('js/jquery-1.12.4.min.js')}}"></script> <style> .paper a{ display:inline-block; color:blue; padding:5px; margin:5px; background-color:yellow; } .paper a.active{ background-color:red; color:white; } </style> </head> <body> <p>输入信息:</p> <form action="/index/{{current_page}}" method="post"> <span>用户名:</span><input type="text" id="userName" name="userName" /> <span>密码:</span><input type="text" id="passWord" name="passWord" /> <input type="submit" value="确定" /> </form> <p>显示信息:</p> <table border="1px"> <tr><td>用户名</td><td>密码</td></tr> {% for item in info_list %} <tr><td>{{ item['name'] }}</td><td>{{ item['pwd'] }}</td></tr> <!--XSS跨站脚本攻击:tornado自动进行字符串处理,取消自动处理使用raw--> <!--<tr><td>{% raw item['name'] %}</td><td>{{ item['pwd'] }}</td></tr>--> {% end %} </table> <div class="paper"> <!--分页控制--> {% raw pageCtrl %} </div> </body> </html>
home.py(模块化)
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.web INFO_LIST = [{'name':'<script>alert(123);</script>','pwd':456},{'name':'dongxue','pwd':456}] # 测试数据 for i in range(99): temp = {'name':'dongxue'+str(i),'pwd':str(i)} INFO_LIST.append(temp) # 分页功能模块 class Pagination: def __init__(self,page,all_item,one_page_item): # page 是当前页,必须是不小于1的整数, try: page = int(page) except: page = 1 if page < 1: page = 1 self.currentPage = page # 当前页 self.one_page_item = one_page_item # 每页显示数据量 # all_item 是数据总量,根据每页显示的数据量,计算出总页码数 self.all_page,c = divmod(all_item,one_page_item) if c > 0: self.all_page += 1 # 总页数 @property def start(self): # 数据切片开始 return (self.currentPage - 1) * self.one_page_item @property def end(self): # 数据切片结束 return self.currentPage * self.one_page_item def pageCtrl(self,baseURL): # 分页码设置 List_pageCTRL = [] if self.all_page <= (self.one_page_item * 2 + 1): s = 0 e = self.all_page else: if self.currentPage <= (self.one_page_item + 1): s = 0 e = (self.one_page_item * 2 + 1) else: if self.currentPage >= (self.all_page - self.one_page_item): s = self.all_page - (self.one_page_item * 2 + 1) e = self.all_page else: s = self.currentPage - (self.one_page_item + 1) e = self.currentPage + self.one_page_item for p in range(s,e): if p+1 == self.currentPage: temp = '<a class="active" href="%s%s">%s</a>'%(baseURL,p+1,p+1) # 当前页重点显示 else: temp = '<a href="%s%s">%s</a>'%(baseURL,p+1,p+1) List_pageCTRL.append(temp) return "".join(List_pageCTRL) # 访问首页 class IndexHandler(tornado.web.RequestHandler): def get(self,page): page_obj = Pagination(page,len(INFO_LIST),5) current_list = INFO_LIST[page_obj.start:page_obj.end] str_pageCtrl = page_obj.pageCtrl('/index/') self.render('home/index.html',info_list = current_list,current_page = page_obj.currentPage,pageCtrl = str_pageCtrl,) def post(self, page): info_item = {} info_item['name'] = self.get_argument('userName',None) info_item['pwd'] = self.get_argument('passWord',None) INFO_LIST.append(info_item) self.redirect('/index/'+page)
分页类可作为单独的模块使用(添加首页和尾页跳转):
# 分页功能模块 class Pagination: def __init__(self,page,all_item,one_page_item): # page 是当前页,必须是不小于1的整数, try: page = int(page) except: page = 1 if page < 1: page = 1 self.currentPage = page # 当前页 self.one_page_item = one_page_item # 每页显示数据量 # all_item 是数据总量,根据每页显示的数据量,计算出总页码数 self.all_page,c = divmod(all_item,one_page_item) if c > 0: self.all_page += 1 # 总页数 @property def start(self): # 数据切片开始 return (self.currentPage - 1) * self.one_page_item @property def end(self): # 数据切片结束 return self.currentPage * self.one_page_item def pageCtrl(self,baseURL): # 分页码设置 List_pageCTRL = [] if self.all_page <= (self.one_page_item * 2 + 1): s = 0 e = self.all_page else: if self.currentPage <= (self.one_page_item + 1): s = 0 e = (self.one_page_item * 2 + 1) else: if self.currentPage >= (self.all_page - self.one_page_item): s = self.all_page - (self.one_page_item * 2 + 1) e = self.all_page else: s = self.currentPage - (self.one_page_item + 1) e = self.currentPage + self.one_page_item first_page = '<a href="%s1">首页</a>'%(baseURL,) # 首页链接 List_pageCTRL.append(first_page) if self.currentPage == 1: prev_page = '<a href="%s%s">上一页</a>'%(baseURL,self.currentPage) else: prev_page = '<a href="%s%s">上一页</a>'%(baseURL,self.currentPage-1) # 上一页链接 List_pageCTRL.append(prev_page) for p in range(s,e): if p+1 == self.currentPage: temp = '<a class="active" href="%s%s">%s</a>'%(baseURL,p+1,p+1) # 当前页重点显示 else: temp = '<a href="%s%s">%s</a>'%(baseURL,p+1,p+1) List_pageCTRL.append(temp) if self.currentPage == self.all_page: next_page = '<a href="%s%s">下一页</a>'%(baseURL,self.currentPage) else: next_page = '<a href="%s%s">下一页</a>'%(baseURL,self.currentPage+1) # 下一页链接 List_pageCTRL.append(next_page) last_page = '<a href="%s%s">尾页</a>'%(baseURL,self.all_page) # 尾页链接 List_pageCTRL.append(last_page) # 跳转至指定页 jump_page = """<input type="text" /> <input type="button" value="GO" onclick="jump(this,%s)" />"""%(baseURL,) jump_page_script = """ <script> function jump(ths,baseUrl){ var val = ths.previousElementSibling.value.trim(); if (val.length >0){ location.href = baseUrl + val; }; }; </script> """ List_pageCTRL.append(jump_page) List_pageCTRL.append(jump_page_script) return "".join(List_pageCTRL)
浙公网安备 33010602011771号