Django 利用 Pagination 簡單分頁


 Django自身提供了一些類來實現管理分頁,數據被分在不同的頁面中,並帶有“上一頁/下一頁”標簽。這個類叫做Pagination,其定義位於 django/core/paginator.py 中。

一. Paginator類的解釋

class Paginator(object): def __init__(self, object_list, per_page, orphans=0, allow_empty_first_page=True): self.object_list = object_list self.per_page = int(per_page) self.orphans = int(orphans) self.allow_empty_first_page = allow_empty_first_page self._num_pages = self._count = None

1.根據其定義做出以下解釋,上述代碼沒有將其類屬性和方法貼出。

  • object_list:可以是列表,元組,查詢集或其他含有 count() 或 __len__()方法的可切片對象。對於連續的分頁,查詢集應該有序,例如有order_by()項或默認ordering參數。
  • per_page:每一頁中包含條目數目的最大值,不包括獨立成頁的那頁。(見下面 orphans參數解釋)。
  • orphans=0:當你使用此參數時說明你不希望最后一頁只有很少的條目。如果最后一頁的條目數少於等於orphans的值,則這些條目會被歸並到上一頁中(此時的上一頁變為最后一頁)。例如有23項條目, per_page=10,orphans=0,則有3頁,分別為10,10,3.如果orphans>=3,則為2頁,分別為10,13。
  • allow_empty_first_page=True: 默認允許第一頁為空。

2.類方法:

  •     Paginator.page(number):根據參數number返回一個Page對象。(number為1的倍數)

3.類屬型:

  • Paginator.count:所有頁面對象總數,即統計object_list中item數目。當計算object_list所含對象的數量時, Paginator會首先嘗試調用object_list.count()如果object_list沒有 count() 方法,Paginator 接着會回退使用len(object_list)
  • Pagnator.num_pages:頁面總數。
  • pagiator.page_range:頁面范圍,從1開始,例如[1,2,3,4]。

 

二. Page類的解釋

 通常不用手動創建Page對象,可以從Paginator.page()來獲得他們。

class Page(collections.Sequence): def __init__(self, object_list, number, paginator): self.object_list = object_list self.number = number self.paginator = paginator

1.類方法

  • Page.has_next()  如果有下一頁,則返回True
  • Page.has_previous() 如果有上一頁,返回 True
  • Page.has_other_pages() 如果有上一頁或下一頁,返回True
  • Page.next_page_number() 返回下一頁的頁碼。如果下一頁不存在,拋出InvlidPage異常。
  • Page.previous_page_number() 返回上一頁的頁碼。如果上一頁不存在,拋出InvalidPage異常。
  • Page.start_index() 返回當前頁上的第一個對象,相對於分頁列表的所有對象的序號,從1開始。比如,將五個對象的列表分為每頁兩個對象,第二頁的start_index()會返回3
  • Page.end_index() 返回當前頁上的最后一個對象,相對於分頁列表的所有對象的序號,從1開始。 比如,將五個對象的列表分為每頁兩個對象,第二頁的end_index() 會返回 4

2.類屬型

  • Page.object_list 當前頁上所有對象的列表。
  • Page.number 當前頁的序號,從1開始。
  • Page.paginator 相關的Paginator對象。

 

三.非法頁面處理

  • InvalidPage(Exception):  異常的基類,當paginator傳入一個無效的頁碼時拋出。

    Paginator.page()放回在所請求的頁面無效(比如不是一個整數)時,或者不包含任何對象時拋出異常。通常,捕獲InvalidPage異常就夠了,但是如果你想更加精細一些,可以捕獲以下兩個異常之一:

  • exception PageNotAnInteger,當向page()提供一個不是整數的值時拋出。
  • exception EmptyPage,當向page()提供一個有效值,但是那個頁面上沒有任何對象時拋出。

       這兩個異常都是InalidPage的子類,所以可以通過簡單的except InvalidPage來處理它們。

 

四.使用Paginator

官方示例:

views.py:

from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render def listing(request): contact_list = Contacts.objects.all() # 獲取所有contacts,假設在models.py中已定義了Contacts模型 paginator = Paginator(contact_list, 25) # 每頁25條
 page = request.GET.get('page') try: contacts = paginator.page(page) # contacts為Page對象! except PageNotAnInteger: # If page is not an integer, deliver first page.
        contacts = paginator.page(1) except EmptyPage: # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages) return render(request, 'list.html', {'contacts': contacts})

list.html:

{% for contact in contacts %} {# Each "contact" is a Contact model object. #}
    {{ contact.full_name|upper }}<br /> ... {% endfor %} <div class="pagination">
    <span class="step-links"> {% if contacts.has_previous %} <a href="?page={{ contacts.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}. </span> {% if contacts.has_next %} <a href="?page={{ contacts.next_page_number }}">next</a> {% endif %} </span>
</div>

 final:  根據官方示例代碼結果如下,頁面共有3頁,首頁時只有next選項,中間頁時可選擇previous 或 next,尾頁時只有previous選項。

 

 

另:給出另一種list.html:

<div id="pagination">
    <ul id="pagination-flickr"> {% if article_list.has_previous %} <li class="previous"><a href="?page={{ article_list.previous_page_number }}{% if request.GET.year %}&year={{ request.GET.year }}{% endif %}{% if request.GET.month %}&month={{ request.GET.month }}{% endif %}{% if request.GET.cid %}&cid={{ request.GET.cid }}{% endif %}">&laquo;上一頁</a></li> {% else %} <li class="previous-off">&laquo;上一頁</li> {% endif %} <li class="active">{{ article_list.number }}/{{ article_list.paginator.num_pages }}</li> {% if article_list.has_next %} <li class="next"><a href="?page={{ article_list.next_page_number }}{% if request.GET.year %}&year={{ request.GET.year }}{% endif %}{% if request.GET.month %}&month={{ request.GET.month }}{% endif %}{% if request.GET.cid %}&cid={{ request.GET.cid }}{% endif %}">下一頁 &raquo;</a></li> {% else %} <li class="next-off">下一頁 &raquo;</li> {% endif %} </ul>
</div>
contacts 和 article_list 是同一個意思,效果如下:

  

 

 

 

 
        


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM