Webpy的分页功能实现

09 Oct, 2011

在做网站的时候,分页功能算是个必须品了,于是也决定试试如何实现分页功能。网上查了一下资料,分页的实现基本上都是以JSP、PHP为例子讲解的,方法也比较多,比较简单容易理解的就是利用查询数据库不同区间的条目来达到分页,于是我以Webpy框架为基础,搞了一下分页,至于效率,这个就不好说了。下面简单说一下我的方法。

webpy分页

分页功能实现原理:这个主要是查询显示的内容条目数,然后根据每页设置的内容数得到总页数,在获取内容时应用SQL查询的limit和offset条件进行约束查询,最后得到这个页面显示的内容,貌似MS SQL不支持这两个条件,不过MySQL、SQLite、postgreSQL都支持,再说Webpy也不支持MS SQL。

原理很简单,做起来也一样简单,只需要掌握两句SQL查询语句就行了,下面是Webpy封装过的查询语句,如果你没使用它封装的,你也可以写出原生的SQL语句。例子我使用的是网上有的那个非常经典的Todo程序。

results = db.query("SELECT COUNT(*) AS todos FROM todo")

这个使用的是高级事务查询,得到表todo中的条目数量——results[0].todos

todos = db.select('todo',order='id desc',limit=NavNum,offset=off)

这个用limit和offset来约束查询结果,NavNum表示最多显示的数量,off表示偏移量,即从第几条开始查询。

有了上面的查询知识,分页就很好实现了,下面是一个显示todo的分页类,这个是基于Webpy的,再次声明一下。

class NavNum(object):

    def GET(self,id):
        NavNum = 5
        results = db.query("SELECT COUNT(*) AS todos FROM todo")
        username = results[0].todos
        if username % NavNum==0:
            pages = username / NavNum
        else:
            pages = username / NavNum + 1
        off = (int(id)-1) * NavNum
        todos = db.select('todo',order='id desc',limit=NavNum,offset=off)
        return render.index(todos,pages)

主要就是在得到页数时,如果总数刚好是NavNum的倍数就比较简单,不是的话需要加1,然后将查询得到的结果和页数返回给模板。模板的代码如下(省略了todo的显示,主要是分页的显示):

$def with(todos,pages)

        <div class="box">
         ...
        <p>Page:
                $for page in range(1,pages+1):
                <a href="/todo/$page">$page</a>
        </p>
            </div>

当然,这个会列出分页代码,不过还没有进行过优化,比如实现只显示一部分页数,突出显示当前页等,实现起来也比较简单。然后是URL的映射:

urls = (
    '/todo/(\d+)',   'NavNum',
)

这样就搞定分页功能了,这是一种最简单的方法,也最好理解,至于有没有其他更高效或者更酷的实现方式,以后看到后再谈谈。现在比较头痛的是文章内容里实现分页,这个得好好研究一下。