1. 程式人生 > >分頁的實現

分頁的實現

spa width 前端 總頁數 pty 實現 渲染 dde 博客系統

分頁的實現

簡述

對於“分頁”,大家肯定再熟悉不過了,當一個網頁的同類的內容在一頁顯示不全的時候,我們通常的解決方案都是在本頁的同一區域做一個類似於“翻書”的功能,在‘第1頁’顯示前幾條內容,‘第2頁’顯示另外的內容,以此類推,本文就為大家介紹在Django中如何實現分頁功能

功能預覽

本博客系統的分頁功能預覽如下:

技術分享圖片

詳細介紹

後臺處理邏輯

首先,我們需要引入PaginatorEmptyPage類,後續的處理都需要依賴於這兩個類。
接著,在index主頁的視圖函數中,我們不僅要獲取本網站需要顯示的所有文章的列表,還需要進行分頁邏輯的處理。

分頁邏輯的設計分為下面幾步

一:首先,要確定每一頁顯示數據的個數,也就是說在獲取所有文章的前提下利用Paginator
類實例化出一個分頁器對象來(我們這裏限定每頁顯示三篇文章):
article_list = models.Article.objects.all()
paginator = Paginator(article_list,3)
註意,第一步實例化出的Paginator對象有三個參數需要大家記住,大家可以中途打印出來驗證一下。
paginator.count         數據的總數
paginator.num_pages     總頁數
paginator.page_range    頁碼的列表
二:接下來需要將當前頁面對象current_page取出來
# 當前頁,默認是第一頁
current_page_c = int(request.GET.get(‘page‘, 1))
current_page = paginator.page(current_page_c)
三:其實在數據量小的情況下做完前兩部就OK了。但是大家考慮下,如果我們的數據量特別大,大到需要分100多頁甚至更多時才能顯示完所有的數據,這樣在網頁中將會有100甚至更多的分頁器數據。這樣顯然是不合理的。為了解決這個問題,我們還需要往模板中返回range對象,用來限制網站中分頁器的頁碼顯示:
# 最多顯示11個格子
# 註意下面的判斷——保證最多顯示11個格子且“左5右5”,如果有越限的進行限制
# page_range_whw存的是range對象
if paginator.num_pages > 11:
    # “左5”越限
    if current_page_c - 5 < 1:
        page_range_whw = range(1, 11)
    # “右5”越限
    elif current_page_c + 5 > paginator.num_pages:
        page_range_whw = range(paginator.num_pages - 10, paginator.num_pages + 1)
    else:
        page_range_whw = range(current_page_c - 5, current_page_c + 6)
else:
    page_range_whw = paginator.page_range

後臺完整代碼

註意,對於分頁器,往後臺傳了兩個對象,一個是當前頁對象current_page,另外一個是range對象page_range_whw
article_list = models.Article.objects.all()
paginator = Paginator(article_list, 3)
# print("count:", paginator.count)  # 數據總數
# print("num_pages", paginator.num_pages)  # 總頁數
# print("page_range", paginator.page_range)  # 頁碼的列表
try:
    # 當前頁,默認是第一頁
    current_page_c = int(request.GET.get(‘page‘, 1))
    current_page = paginator.page(current_page_c)
    # 最多顯示11個格子
    # 註意下面的判斷——保證最多顯示11個格子且“左5右5”,如果有越限的進行限制
    # page_range_whw存的是range對象
    if paginator.num_pages > 11:
        # “左5”越限
        if current_page_c - 5 < 1:
            page_range_whw = range(1, 11)
        # “右5”越限
        elif current_page_c + 5 > paginator.num_pages:
            page_range_whw = range(paginator.num_pages - 10, paginator.num_pages + 1)
        else:
            page_range_whw = range(current_page_c - 5, current_page_c + 6)
    else:
        page_range_whw = paginator.page_range
except EmptyPage as e:
    current_page = paginator.page(1)
return render(request,‘index.html‘,locals())

前端模板的渲染

對於前端模板的渲染比較簡單,這裏就不做詳細的介紹了,但是,需要註意的一點是,由於我們做了分頁器,那麽在‘遍歷‘文章列表的時候,我們遍歷的對象不再是‘article_list’了,而是當前頁對象‘current_page‘,這一點要特別註意!

文章列表渲染與分頁器前端實現的代碼

{# 文章列表部分 #}
<div class="col-md-6">
    <div class="article-list" style="position: fixed;width: 46%;">
        {# 註意,做分頁的時候,循環“當前頁”而不是所有的article_list #}
        {% for article in current_page %}
            <div class="article-item">
                <h5><a href="/{{ article.user }}/articles/{{ article.pk }}/">{{ article.title }}</a></h5>
                <div class="article-desc">
                    <span class="media-left">
                                                                                  {# 正向查詢按字段 #}
                        <a href=""><img width="55px" height="55px" src="media/{{ article.user.avatar }}" ></a>
                    </span>
                    <span class="media-right">
                        {{ article.desc }}
                    </span>
                </div>
                <div class="small pub_info">
                                        {# 正向查詢按字段 #}
                    <span><a href="">{{ article.user.username }}</a></span>&nbsp;&nbsp;
                    <span><a href="">發布於 {{ article.create_date|date:‘Y-m-d H:i‘ }}</a></span>&nbsp;&nbsp;
                    <span class="glyphicon glyphicon-comment"></span>評論({{ article.content_count }})&nbsp;&nbsp;
                    <span class="glyphicon glyphicon-thumbs-up"></span>點贊({{ article.up_count }})
                    <hr>
                </div>
            </div>
        {% endfor %}
    </div>
    {# 分頁器 #}
    <div style="position: fixed;margin-top: 38%">
        <nav aria-label="Page navigation">
            <ul class="pagination">
                {% if current_page.has_previous %}
                    <li><a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
                            <span aria-hidden="true">上一頁</span></a></li>
                {% else %}
                    <li class="disabled"><a href="" aria-label="Previous">
                            <span aria-hidden="true">上一頁</span></a></li>
                {% endif %}

                {% for item in page_range_whw %}
                    {% if current_page_c == item %}
                        <li class="active"><a href="?page={{ item }}">{{ item }}</a></li>
                    {% else %}
                        <li><a href="?page={{ item }}">{{ item }}</a></li>
                    {% endif %}
                {% endfor %}

                {% if current_page.has_next %}
                    <li><a href="?page={{ current_page.next_page_number }}" aria-label="Next">
                            <span aria-hidden="true">下一頁</span></a></li>
                {% else %}
                    <li class="disabled"><a href="" aria-label="Next"><span aria-hidden="true">下一頁</span></a>
                    </li>
                {% endif %}
            </ul>
        </nav>
    </div>
</div>

分頁的實現