利用Flask-SQLAlchemy提供的paginate()方法实现博客文章的分页显示

在开发blog系统的时候,咱们有一个需求,就是要显示做者已经发表的blog文章的列表,或显示做者关注者的文章列表。实现这个功能并不复杂,只须要在存储文章的数据库中过滤出指定做者的文章,而后渲染HTML显示便可。 
可是,这种方法在文章很少的状况下或许是可行的,当文章的数量变多的时候,就没法在一页中显示完全部的文章了。这时就须要将文章列表进行分页显示,每一页只显示指定数量的文章。 
这个功能应该如何实现呢?咱们能想到的一个直观的方法就是将从数据库中过滤获得的文章列表进行分组,每次只显示一组文章。而后根据用户的须要来显示指定组的文章列表。 
俗话说:Talk is cheap ,show me the code .以上这些该如何落实到代码中呢?Flask-SQLAlchemy能够祝咱们一臂之力。Flask-SQLAlchemy提供的paginate()方法能够实现按照指定的数量来对从数据库中获得的文章列表进行分组。那么有了文章列表的分组,咱们该如何指定显示哪一个分组呢?这就须要在HTML页面中添加一个分页导航栏了,有了这个分页导航栏,用户就能够根据须要显示指定的文章列表分组了。那么这个分页导航栏又该如何实现呢?让咱们仍是回到Flask-SQLAlchemy提供的paginate()方法中来,paginate()方法的返回值是一个Pagination类对象,这个类在Flask-SQLAlchemy中定义。这个类包含不少的属性,能够用来在模板中生成分页的连接,所以能够将其做为参数传入模板。 
Pagination类对象的属性主要有: 
has_next:若是在目前页后至少还有一页的话,返回 True。 
has_prev:若是在目前页以前至少还有一页的话,返回 True。 
next_num:下一页的页面数。 
prev_num:前一页的页面数。 
另外还有以下的可调用方法: 
iter_pages():一个迭代器,返回一个在分页导航中显示的页数列表。 
prev():上一页的分页对象。 
next():下一页的分页对象。 
关于Pagination类对象的属性和方法的详细介绍, 
请参考 
下面让咱们先看一看如何将过滤获得的文章列表进行分组。 
假设咱们的文章存储在post表中,在ORM中的名字是Post。

@main.route('/', methods=['GET', 'POST'])
def index():
    page = request.args.get('page', 1, type=int)    
    pagination = Post.query.order_by(Post.timestamp.desc()).paginate(page,per_page=current_app.config['ARTISAN_POSTS_PER_PAGE'],error_out=False)
    posts = pagination.items
    return render_template('index.html', form=form, posts=posts,                          pagination=pagination)

在Bootstrap中有分页的css类,咱们能够利用这个类在模板中构建分页导航,利用jinjia2宏的形式实现的分页导航代码以下:

<ul class="posts">
    {% for post in posts %}
    <li class="post">
        <div class="post-thumbnail">
            <a href="{{ url_for('.user', username=post.author.username) }}">
                 <img class="img-rounded profile-thumbnail" src="{{ post.author.image }}">
            </a>
        </div>
        <div class="post-content">
            <div class="post-date">{{ moment(post.timestamp).fromNow() }}</div>
            <div class="post-author"><a href="{{ url_for('.user', username=post.author.username) }}">{{ post.author.username }}</a></div>
            <div class="post-body">
                {% if post.body_html %}
                    {{ post.body_html | safe }}
                 {% else %}
                     {{ post.body }}
                {% endif %}
            </div>
            <div class="post-footer">
                {% if current_user == post.author %}
                <a href="{{ url_for('.edit',id=post.id)}}">
                    <span class="label label-primary">Edit</span>
                </a>
                {% elif current_user.is_adminstrator() %}
                 <a href="{{ url_for('.edit',id=post.id)}}">
                    <span class="label label-primary">Edit [Admin]</span>
                 </a>
                {% endif %}
                <a href="{{ url_for('.post',id=post.id) }}">
                    <span class="label label-default">Permalink</span>
                </a>
            </div>
        </div>
    </li>
    {% endfor %}
</ul>

在主页中显示导航栏的代码以下:、

<div class="pagination">
    {{ macros.pagination_widget(pagination, '.index') }}
</div>
相关文章
相关标签/搜索