当博客文章达到一定数量的时候,把它们都放在同一个列表页面不是一个明智的选择,因为这样会使页面过大从而影响加载速度,影响读者的阅读体验。所以我们需要一个粉页的功能。在网上搜索了一下,大部分关于Flask的分页都基于SQLAlchemy,但是我们并不是通过数据库来管理文件的。我们需要一种更为通用的方法,构建我们自己的切片方法并设置正确的路由。
切片
首先我们需要对文章列表进行切片,在这里我们声明一个Pagination的类来获得不同部分的文章列表
1 2 | import math class Pagination(object): |
Pagination需要三个参数,分别是:
- page 当前页面页码
- per_page 每页显示数目
- 文章列表(需要被切片的对象),使用len可获得总文章数
1 2 3 4 5
def __init__(self,page,per_page,iterable): self.page = page self.per_page = per_page self.iterable = iterable self.total = len(iterable)
之后我们通过定义类方法来获得
-
页面总数
1 2 3
@property def total_pages(self): return int(math.ceil(self.total/self.per_page))
-
是否有”上一页/下一页”,如果有返回True,否则False
1 2 3 4 5 6 7
@property def has_prev(self): return self.page > 1 @property def has_next(self): return self.page < self.total_pages
-
页码列表
1 2 3 4
@property def pager(self): #返回[1,2,3,...,n] return list(range(1,self.total_pages+1))
-
切片后的当前页面列表
1 2 3 4 5 6 7 8
@property def items(self): index = self.page - 1 start = index * self.per_page end = start + self.per_page #如果当前第二页,每页6篇文章 #则会返回第7-12篇文章的列表 return self.iterable[start:end]
-
切片后的当前页面列表
路由
- 设置路由
1 2 3
@postwall.route('/posts')#默认第一页路径为http://你的网站/posts @postwall.route('/posts/page/<int:page>/')#从第二页开始的路径 def posts(page = 1):#page = 1是默认第一页的时候page为1
其中page参数与‘int:page'对应,是页码的参数,并作为参数传入Pagination类
-
使用Pagination类切片
1 2
PER_PAGE = 6 page_list = Pagination(page,PER_PAGE,sorted_posts)
-
将切片后的对象返回给模板:
1
return render_template('posts.html',pagination = page_list)
在使用分页之前,由于我们只需要将所有页码加入到主页当中,所以我们只需要将文章列表传入模板,而现在我们使用了切片的Pagination类,这时候传入模板的是一个类对象而不是列表
模板生成
首先我们先创建一个模板的Marco模块pagination.html来表示我们生成页码的过程,pagination就是我们通过路由引入的切片后的类对象
‘pagination = page_list‘
第一行定义macro