Пагинация
Django предоставляет высокоуровневые и низкоуровневые способы управления постраничной передачей данных — то есть данными, которые разделены на несколько страниц с ссылками «Предыдущая/Следующая».
Класс Paginator
Внутри всех методов пагинации используется класс Paginator. Он выполняет всю основную работу по разделению QuerySet на объекты Page.
Пример
Передайте Paginator список объектов и количество элементов на странице, и он предоставит вам методы для доступа к элементам каждой страницы:
>>> 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) >>> 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 список/кортеж, Django QuerySet, или любой другой объект с методом count() или __len__(). При определении количества объектов в переданном объекте, Paginator сначала попытается вызвать count(), а затем использует len(), если у переданного объекта нет метода count(). Это позволяет объектам, таким как Django QuerySet, использовать более эффективный метод count() при его наличии.
Пагинация списка
django.views.generic.list.ListView предоставляет встроенный способ постраничного отображения списка. Вы можете сделать это, добавив атрибут paginate_by в ваш класс представления, например:
from django.views.generic import ListView
from myapp.models import Contact
class ContactListView(ListView):
paginate_by = 2
model = Contact
Это ограничивает количество объектов на странице и добавляет ссылки «следующая страница» и «предыдущая страница» к context. Чтобы позволить пользователям переходить между страницами, добавьте ссылки на следующую и предыдущую страницы в ваш шаблон, как показано ниже:
{% for contact in page_obj %}
{# Each "contact" is a Contact model object. #}
{{ contact.full_name|upper }}<br>
...
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
<a href="?page=1">« first</a>
<a href="?page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}">next</a>
<a href="?page={{ page_obj.paginator.num_pages }}">last »</a>
{% endif %}
</span>
</div>
Использование Paginator в представлении
Вот пример использования Paginator в функции представления для постраничной обработки набора запросов:
from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import Contact
def listing(request):
contact_list = Contact.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page.
page_number = request.GET.get("page")
page_obj = paginator.get_page(page_number)
return render(request, "list.html", {"page_obj": page_obj})
В шаблоне list.html, вы можете включить навигацию между страницами так же, как и в шаблоне для ListView выше.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.0/topics/pagination/