利用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>
相關文章
相關標籤/搜索