一. Pagination类对象的属性及方法
paginate()方法的返回值是一个Pagination类对象,这个类在Flask-SQLAlchemy中定义。这个类包含很多属性,用于在模板中生成分页链接,因此将其作为参数传入了模板。
属性 | 说明 |
items | 当前页的记录 |
query | 分页的源查询(可打印此属性,查看原生的SQL语句) |
page | 当前页的页数 |
prev_num | 上一页的页数 |
next_num | 下一页的页数 |
has_prev | 如果有上一页返回True |
has_next | 如果有下一页返回True |
pages | 查询得到的总页数 |
per_page | 每页显示的记录总量 |
tatal | 查询返回的记录总数 |
方法 | 说明 |
iter_pages(left_edge=2, left_current=2, right_current=5, right_edge=2) | 一个迭代器,返回一个在分页导航中显示的页数列表。列入,在一个100页的列表中,当前页为第50页,使用默认配置,这个方法将返回以下页数:1,2,None,48,49,50,51,52,53,54,55,None,99,100。 |
prev() | 上一页的分页对象 |
next() | 下一页的分页对象 |
二. 实现分页模板宏
借助Pagination分页对象和BootStrap中的分页CSS类,我们很轻易就能在模板底部构建一个分页导航。
app/templates/_macros.html:分页模板宏
{% macro pagination_widget(pagination, endpoint) %}
<ul class="pagination">
<li{% if not pagination.has_prev %} class="disabled"{% endif %}>
<a href="{% if pagination.has_prev %}{{ url_for(endpoint, page=pagination.prev_num, **kwargs) }}{% else %}#{% endif %}">
«
</a>
</li>
{% for p in pagination.iter_pages() %}
{% if p %}
{% if p == pagination.page %}
<li class="active">
<a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>
</li>
{% else %}
<li>
<a href="{{ url_for(endpoint, page = p, **kwargs) }}">{{ p }}</a>
</li>
{% endif %}
{% else %}
<li class="disabled"><a href="#">…</a></li>
{% endif %}
{% endfor %}
<li{% if not pagination.has_next %} class="disabled"{% endif %}>
<a href="{% if pagination.has_next %}{{ url_for(endpoint, page=pagination.next_num, **kwargs) }}{% else %}#{% endif %}">
»
</a>
</li>
</ul>
{% endmacro %}
这个宏创建了一个BootStrap分页元素,即一个有特殊样式的分页列表,此页面元素包含三部分:
- “上一页”链接。如果当前页是第一页,则这个元素需要加上disabled类;若存在上一页,则使用url_for生成上一页的href;
- 遍历iter_pages()迭代器时,首先需要判断页数是否为None,为None时渲染...;不为None时,继续判断是否为当前页,并将当前页使用active CSS类高亮显示;
- “下一页链接”。如果当前页已是最后一页,则会禁用这个链接;
注意:创建页面链接时使用“{{ url_for(endpoint, page = p, **kwargs) }}”,而宏{% macro pagination_widget(pagination, endpoint) %}定义时并没有定义**kwargs。那是因为Jinja2 宏的参数列表中不用加入 **kwargs 即可接收关键字参数。
此处分页宏把所接收到的所有关键字参数都传给了生成分页链接的url_for()方法。这样做是为了增加灵活性和通用性,因为资料页面的路由不仅需要page查询参数,还包含动态路由的参数。
三. 在首页和资料页添加分页导航
pagination_widget 宏可放在 index.html 和 user.html 中的 _posts.html 模板后面。
app/templates/index.html:在博客文章列表下面添加分页导航
{% import "_macros.html" as macros %}
...
{% if pagination %}
<div class="pagination">
{{ macros.pagination_widget(pagination, '.index') }}
</div>
{% endif %}
app/templates/user.html资料页使用同样的方式添加博客分页导航。
运行结果:
详情页只显示自己发布的博客文章: