Django提供了一些類來(lái)幫助你管理分頁(yè)的數(shù)據(jù) -- 也就是說(shuō),數(shù)據(jù)被分在不同頁(yè)面中,并帶有“上一頁(yè)/下一頁(yè)”標(biāo)簽。這些類位于django/core/paginator.py中。
向Paginator提供對(duì)象的列表,以及你想為每一頁(yè)分配的元素?cái)?shù)量,它就會(huì)為你提供訪問每一頁(yè)上對(duì)象的方法:
>>> 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()
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> 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)
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3)
Traceback (most recent call last):
...
EmptyPage: That page contains no results
注意
注意你可以向Paginator提供一個(gè)列表或元組,Django的QuerySet,或者任何帶有count()或__len__()方法的對(duì)象。當(dāng)計(jì)算傳入的對(duì)象所含對(duì)象的數(shù)量時(shí),Paginator會(huì)首先嘗試調(diào)用count(),接著如果傳入的對(duì)象沒有count()方法則回退調(diào)用 len()。這樣會(huì)使類似于Django的QuerySet的對(duì)象使用更加高效的 count()方法,如果存在的話。
Paginator這里有一些復(fù)雜一點(diǎn)的例子,它們?cè)谝晥D中使用 Paginator 來(lái)為查詢集分頁(yè)。我們提供視圖以及相關(guān)的模板來(lái)展示如何展示這些結(jié)果。這個(gè)例子假設(shè)你擁有一個(gè)已經(jīng)導(dǎo)入的Contacts模型。
視圖函數(shù)看起來(lái)像是這樣:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def listing(request):
contact_list = Contacts.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page
page = request.GET.get('page')
try:
contacts = paginator.page(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_to_response('list.html', {"contacts": contacts})
在list.html模板中,你會(huì)想要包含頁(yè)面之間的導(dǎo)航,以及來(lái)自對(duì)象本身的任何有趣的信息:
<div class="pagination">
<span class="step-links">
<span class="current">
Page of .
</span>
</span>
</div>
Paginator類擁有以下構(gòu)造器:
class Paginator(_objectlist, _perpage, orphans=0, _allow_empty_firstpage=True)[source]
object_list
A list, tuple, Django QuerySet, or other sliceable object with a
count() or __len__() method.
per_page
The maximum number of items to include on a page, not including orphans
(see the orphans optional argument below).
orphans
The minimum number of items allowed on the last page, defaults to zero.
Use this when you don’t want to have a last page with very few items.
If the last page would normally have a number of items less than or equal
to orphans, then those items will be added to the previous page (which
becomes the last page) instead of leaving the items on a page by
themselves. For example, with 23 items, per_page=10, and
orphans=3, there will be two pages; the first page with 10 items and
the second (and last) page with 13 items.
allow_empty_first_page
Whether or not the first page is allowed to be empty. If False and
object_list is empty, then an EmptyPage error will be raised.
Paginator.``page(number)[source]
返回在提供的下標(biāo)處的Page對(duì)象,下標(biāo)以1開始。如果提供的頁(yè)碼不存在,拋出InvalidPage異常。
Paginator.``count
所有頁(yè)面的對(duì)象總數(shù)。
注意
當(dāng)計(jì)算object_list所含對(duì)象的數(shù)量時(shí), Paginator會(huì)首先嘗試調(diào)用object_list.count()。如果object_list沒有 count() 方法,Paginator 接著會(huì)回退使用len(object_list)。這樣會(huì)使類似于Django’s QuerySet的對(duì)象使用更加便捷的count()方法,如果存在的話。
Paginator.``num_pages
頁(yè)面總數(shù)。
Paginator.``page_range
頁(yè)碼的范圍,從1開始,例如[1, 2, 3, 4]。
exception InvalidPage[source]
異常的基類,當(dāng)paginator傳入一個(gè)無(wú)效的頁(yè)碼時(shí)拋出。
Paginator.page()放回在所請(qǐng)求的頁(yè)面無(wú)效(比如不是一個(gè)整數(shù))時(shí),或者不包含任何對(duì)象時(shí)拋出異常。通常,捕獲InvalidPage異常就夠了,但是如果你想更加精細(xì)一些,可以捕獲以下兩個(gè)異常之一:
exception PageNotAnInteger[source]
當(dāng)向page()提供一個(gè)不是整數(shù)的值時(shí)拋出。
exception EmptyPage[source]
當(dāng)向page()提供一個(gè)有效值,但是那個(gè)頁(yè)面上沒有任何對(duì)象時(shí)拋出。
這兩個(gè)異常都是InvalidPage的子類,所以你可以通過(guò)簡(jiǎn)單的except InvalidPage來(lái)處理它們。
你通常不需要手動(dòng)構(gòu)建 Page對(duì)象 -- 你可以從Paginator.page()來(lái)獲得它們。
class Page(_objectlist, number, paginator)[source]
當(dāng)調(diào)用len()或者直接迭代一個(gè)頁(yè)面的時(shí)候,它的行為類似于 Page.object_list 的序列。
Page.``has_next()[source]
Returns True if there’s a next page.
Page.``has_previous()[source]
如果有上一頁(yè),返回 True。
Page.``has_other_pages()[source]
如果有上一頁(yè)_或_下一頁(yè),返回True。
Page.``next_page_number()[source]
返回下一頁(yè)的頁(yè)碼。如果下一頁(yè)不存在,拋出InvalidPage異常。
Page.``previous_page_number()[source]
返回上一頁(yè)的頁(yè)碼。如果上一頁(yè)不存在,拋出InvalidPage異常。
Page.``start_index()[source]
返回當(dāng)前頁(yè)上的第一個(gè)對(duì)象,相對(duì)于分頁(yè)列表的所有對(duì)象的序號(hào),從1開始。比如,將五個(gè)對(duì)象的列表分為每頁(yè)兩個(gè)對(duì)象,第二頁(yè)的start_index()會(huì)返回3。
Page.``end_index()[source]
返回當(dāng)前頁(yè)上的最后一個(gè)對(duì)象,相對(duì)于分頁(yè)列表的所有對(duì)象的序號(hào),從1開始。 比如,將五個(gè)對(duì)象的列表分為每頁(yè)兩個(gè)對(duì)象,第二頁(yè)的end_index() 會(huì)返回 4。
Page.``object_list
當(dāng)前頁(yè)上所有對(duì)象的列表。
Page.``number
當(dāng)前頁(yè)的序號(hào),從1開始。
Page.``paginator
相關(guān)的Paginator對(duì)象。
譯者:Django 文檔協(xié)作翻譯小組,原文:Pagination。
本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請(qǐng)保留作者署名和文章出處。
Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。