使用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()
View Code

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)
View Code

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>
View Code

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)
View Code

分页类可作为单独的模块使用(添加首页和尾页跳转):

# 分页功能模块
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)
View Code