Django-利用paginator模塊實現分頁


Django專門提供了一個paginator模塊,實現分頁很easy。

下面的例子引用了django官方文檔:https://docs.djangoproject.com/en/1.11/topics/pagination/

使用Paginator類

Paginator實例化需要2個參數,一個是待分頁的對象list(需要實現count方法或者__len__方法),另一個是每頁數量。 
Paginator對象屬性:

count 對象數量 
num_pages 總頁數 
page_range 所有頁數范圍的生成器
>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)

>>> p.count
4
>>> p.num_pages
2
>>> type(p.page_range)
<class 'range_iterator'>
>>> p.page_range
range(1, 3)

Paginator對象的重要方法,page(),接受一個頁碼作為參數,返回一個當前頁對象。該對象的幾個屬性和方法:

object_list 當前頁的對象列表 
has_next() 有無下一頁 
has_ previous() 有無上一頁 
has_other_pages() 有無其他頁 
next_page_number() 下一頁頁碼 
previous_page_number() 上一頁頁碼 
start_index() 返回當前頁第一個對象的在所有對象中的索引,注意,從1開始 
end_index() 返回當前頁最后一個對象在所有對象中的索引,注意,從1開始 
paginator 所關聯的Paginator對象
>>> 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

Pagenator的page方法,若傳給一個無頁碼范圍之外都值,則得到一個EmptyPage的異常。

>>> 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

在視圖中可以這么用:

# views.py
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.shortcuts import render

def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # 每頁顯示25個

    page = request.GET.get('page') # 拿到頁碼參數
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # 捕獲到頁碼不是整數,返回第一頁
        contacts = paginator.page(1)
    except EmptyPage:
        # 頁碼超出范圍,返回最后一頁
        contacts = paginator.page(paginator.num_pages)

    return render(request, 'list.html', {'contacts': contacts})

contacts對象是用帶有分頁信息的QuerySet,用來渲染模板: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>

基於模型類的視圖,只需給paginate_by賦值(每頁個數)就可以了,似乎是更簡單:

class BookListView(generic.ListView):
    model = Book
    context_object_name = 'book_list'
    template_name = 'catalog/book_list.html'
    paginate_by = 10

模板是通用的,在模板中,可以調用is_paginated 判斷是否有分頁信息。在用page_obj對象實現分頁。

{% block pagination %}
  {% if is_paginated %}
    <div class="pagination">
      <span class="pagelinks">
        {% if page_obj.has_previous %}
          <a href="{{ request.path }}?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <span class="page-current">
          Page{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>
        {% if page_obj.has_next %}
        <a href="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
        {% endif %}
      </span>
    </div>
  {% endif %}
{% endblock %}

 


免責聲明!

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



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