隨着時間的推移(加上勤奮的寫做!),你的博客文章必定會愈來愈多。若是不進行處理,可能同一個頁面會擠上成百上千的文章,不美觀不說,還下降了頁面的反應速度。html
這個時候就須要對文章進行分頁的處理。python
寫一個完善的分頁功能是有些難度的,好在Django已經幫你準備好一個現成的分頁模塊了(Django把大部分基礎功能都替你準備好了!)。內置模塊雖然簡單,可是對博客來講徹底足夠了。git
咱們要用到的是Paginator
類。在Shell
中能夠充分嘗試它的用法:github
>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)
>>> p.count
4
>>> p.num_pages
2
>>> p.page_range
range(1, 3)
>>> page1 = p.page(1)
>>> page1
<Page 1 of 2>
>>> page1.object_list
['john', 'paul']
>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next()
False
>>> page2.has_previous()
True
>>> page2.has_other_pages()
True
>>> page2.previous_page_number()
1
複製代碼
這是一個官網的例子。詳見:Paginationdjango
有了這個類,剩下的工做就是把它應用到項目中去。bootstrap
要對文章列表分頁,所以就要修改article/views.py
的def article_list()
視圖:測試
article/views.py
...
# 引入分頁模塊
from django.core.paginator import Paginator
def article_list(request):
# 修改變量名稱(articles -> article_list)
article_list = ArticlePost.objects.all()
# 每頁顯示 1 篇文章
paginator = Paginator(article_list, 1)
# 獲取 url 中的頁碼
page = request.GET.get('page')
# 將導航對象相應的頁碼內容返回給 articles
articles = paginator.get_page(page)
context = { 'articles': articles }
return render(request, 'article/list.html', context)
...
複製代碼
在視圖中經過Paginator
類,給傳遞給模板的內容作了手腳:返回的再也不是全部文章的集合,而是對應頁碼的部分文章的對象,而且這個對象還包含了分頁的方法。網站
咱們在前面的文章已經接觸過一些將參數傳遞到視圖的手段了:url
這裏用到了另外一種方法:在GET請求中,在url的末尾附上?key=value
的鍵值對,視圖中就能夠經過request.GET.get('key')
來查詢value
的值。spa
而後改寫模板,在最末尾的</div>
前面,加入分頁的內容:
templates/article/list.html
...
<!-- 頁碼導航 -->
<div class="pagination row">
<div class="m-auto">
<span class="step-links">
<!-- 若是不是第一頁,則顯示上翻按鈕 -->
{% if articles.has_previous %}
<a href="?page=1" class="btn btn-success">
« 1
</a>
<span>...</span>
<a href="?page={{ articles.previous_page_number }}" class="btn btn-secondary" >
{{ articles.previous_page_number }}
</a>
{% endif %}
<!-- 當前頁面 -->
<span class="current btn btn-danger btn-lg">
{{ articles.number }}
</span>
<!-- 若是不是最末頁,則顯示下翻按鈕 -->
{% if articles.has_next %}
<a href="?page={{ articles.next_page_number }}" class="btn btn-secondary" >
{{ articles.next_page_number }}
</a>
<span>...</span>
<a href="?page={{ articles.paginator.num_pages }}" class="btn btn-success" >
{{ articles.paginator.num_pages }} »
</a>
{% endif %}
</span>
</div>
</div>
...
複製代碼
內容也比較簡單,用到了前面的Shell
中演示的部分方法,判斷當前頁所處的位置。
這樣就好了!補充幾篇文章(筆者共6篇),方便測試。刷新頁面後是這樣的:
視圖中設置了每頁只有1篇文章,因此就真的只有1篇了。
固然這只是爲了測試,實際環境中確定要遠大於1篇的。
點擊第2頁的按鈕後是這樣的:
看到頂部地址欄中的變化了嗎?
思考一下page
是如何從模板傳遞到視圖的。
除模板外,咱們只寫了4行代碼,就有了還不錯的分頁導航,Django就是這麼貼心。
除了對文章列表,你能夠對任何你想分頁的地方運用此模塊(好比之後要講到的評論),知足用戶各種的需求。
讀者還能夠稍加閱讀Bootstrap 4官方文檔,改寫一個符合本身品味的外觀。
轉載請並註明出處。