Django:使用Paginator進行自動分頁

翻譯自官方文檔

分頁機制

Django 1.0 中分頁機制和先前已經大不相同。它提供了一些類協助你把數據分頁。 對應的文件爲 django/core/paginator.py

舉例

類Paginator,帶兩個構造參數,一個就是數據的集合,另一個表示每頁放幾個數據。

>>> 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
[1, 2]

>>> 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.next_page_number()
3
>>> page2.previous_page_number()
1
>>> page2.start_index() # The 1-based index of the first item on this page
3
>>> page2.end_index() # The 1-based index of the last item on this page
4


>>> p.page(0)
...
EmptyPage: That page number is less than 1
>>> p.page(3)
...
EmptyPage: That page contains no results
Note

Paginator 的第一個參數可以是list,tuple,QuerySet 或者任意對象————只要它 有 count() 或者 __len__() 函數。 Django後臺會先嚐試調用 count()``。如果 不可行,再定要 ``len()

在視圖中使用 Paginator

下面是一個複雜點的分頁例子。也就是把查詢子集在視圖中分頁顯示。下面演示瞭如何結合視圖 view,模板template來顯示結果。前提是假設``Contacts`` model 已經被導入。

視圖view 函數:

from django.core.paginator import Paginator, InvalidPage, EmptyPage
def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        contacts = paginator.page(page)
    except (EmptyPage, InvalidPage):
        contacts = paginator.page(paginator.num_pages)

    return render_to_response('list.html', {"contacts": contacts})

在模板文件 list.html 中,將顯示每個對象的一些信息,以及導航標記。:

{% for contact in contacts.object_list %}
    {# 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>

構造函數:

Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)

必傳參數

object_list

一個list,tuple,django的QuerySet,或者擁有``count()``或``__len__()``方法的 可分解對象。

per_page

每一頁最大的對象個數。

可選參數

orphans

最後一頁對象的最少數目,默認爲0。 如果想避免最後一頁顯示太少。則可以使用這個值。 那麼最後一頁的數據,自動被前移一頁。比如總共23個數據。每頁顯示 10. orphans=3 那麼,第一頁爲10,第二頁爲13.

allow_empty_first_page

表示首頁是否可以爲空,如果是 False 而且``object_list`` 爲空,那麼會觸發 EmptyPage 異常。

方法

Paginator.page(number)

根據索引number,返回一個’Page’對象,如果不存在,引起 InvalidPage異常

屬性

Paginator.count

所有對象的總數, 嘗試通過``object_list.count()``和``object_list.__len__()`` 取得

Paginator.num_pages

總共的頁數

Paginator.page_range

頁的範圍,比如 [1, 2, 3, 4]

InvalidPage 異常

當頁面不存在或者無效時,會引起``InvalidPage``異常,一般這個異常就夠用,如果需要更 詳細信息,還有``PageNotAnInteger``,``EmptyPage``可用:

PageNotAnInteger

page() 的參數非整數。

EmptyPage

page(x) ,第x頁沒數據。

上述兩個都是 InvalidPage 的子類。 用一個簡單的 except InvalidPage 就可以處理。

Page

Page(object_list, number, paginator):

一般不需用戶自己構造,通過`Paginator.page` 生成。

方法

Page.has_next()

如果下一頁存在,返回True。

Page.has_previous()

如果前一頁存在返回 True

Page.has_other_pages()

如果上一頁面或者下一頁存在,返回``True``

Page.next_page_number()

返回下一頁的索引,這個函數比較傻(不管下一頁是否存在,都是簡單的+1)

Page.previous_page_number()

返回上一頁的索引,其他同上

Page.start_index()

返回當前頁,第一個對象的索引。

Page.end_index()

道理同上。

屬性

Page.object_list

當前頁對象列表

Page.number

當前頁的索引

Page.paginator

和page相關的分頁類

發佈了51 篇原創文章 · 獲贊 6 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章