示例:分页

对于互联网上每一个具有一定规模的网站来说,分页程序都是必不可少的:新闻站点、博客、论坛、搜索引擎等等,都会使用分页程序将数量众多的信息分割为多个页面,使得用户可以以页为单位浏览网站提供的信息,并以此来控制网站每次取出的信息数量。图 4-19 就展示了一个使用分页程序对用户发表的论坛主题进行分割的例子。


图 4-19 论坛中的分页示例_images/IMAGE_V2EX_PAGING.png


代码清单 4-2 展示了一个使用列表实现分页程序的方法,这个程序可以将给定的元素有序地放入到一个列表里面,然后使用 LRANGE 命令从列表中取出指定数量的元素,从而实现分页这一概念。


代码清单 4-2 使用列表实现的分页程序:/list/paging.py

  1. class Paging:
  2.  
  3. def __init__(self, client, key):
  4. self.client = client
  5. self.key = key
  6.  
  7. def add(self, item):
  8. """
  9. 将给定元素添加到分页列表中。
  10. """
  11. self.client.lpush(self.key, item)
  12.  
  13. def get_page(self, page_number, item_per_page):
  14. """
  15. 从指定页数中取出指定数量的元素。
  16. """
  17. # 根据给定的 page_number (页数)和 item_per_page (每页包含的元素数量)
  18. # 计算出指定分页元素在列表中所处的索引范围
  19. # 例子:如果 page_number = 1 , item_per_page = 10
  20. # 那么程序计算得出的起始索引就是 0 ,而结束索引则是 9
  21. start_index = (page_number - 1) * item_per_page
  22. end_index = page_number * item_per_page - 1
  23. # 根据索引范围从列表中获取分页元素
  24. return self.client.lrange(self.key, start_index, end_index)
  25.  
  26. def size(self):
  27. """
  28. 返回列表目前包含的分页元素数量。
  29. """
  30. return self.client.llen(self.key)

作为例子,我们可以通过执行以下代码,载入并创建出一个针对用户帖子的分页对象:

  1. >>> from redis import Redis
  2. >>> from paging import Paging
  3. >>> client = Redis(decode_responses=True)
  4. >>> topics = Paging(client, "user-topics")

并使用数字 119 作为用户帖子的 ID ,将它们添加到分页列表里面:

  1. >>> for i in range(20):
  2. ... topics.add(i)
  3. ...

然后我们就可以使用分页程序,对这些帖子进行分页了:

  1. >>> topics.get_page(1, 5) # 以每页 5 个帖子的方式,取出第 1 页的帖子
  2. ['19', '18', '17', '16', '15']
  3. >>> topics.get_page(2, 5) # 以每页 5 个帖子的方式,取出第 2 页的帖子
  4. ['14', '13', '12', '11', '10']
  5. >>> topics.get_page(1, 10) # 以每页 10 个帖子的方式,取出第 3 页的帖子
  6. ['19', '18', '17', '16', '15', '14', '13', '12', '11', '10']

最后,我们可以通过执行以下代码,取得分页列表目前包含的元素数量:

  1. >>> topics.size()
  2. 20