========== Pagination ========== Django provides high-level and low-level ways to help you manage paginated data -- that is, data that's split across several pages, with "Previous/Next" links. The ``Paginator`` class ======================= Under the hood, all methods of pagination use the :class:`~django.core.paginator.Paginator` class. It does all the heavy lifting of actually splitting a ``QuerySet`` into parts and handing them over to other components. Example ======= Give :class:`~django.core.paginator.Paginator` a list of objects, plus the number of items you'd like to have on each page, and it gives you methods for accessing the items for each page:: >>> 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) >>> p.page_range range(1, 3) >>> page1 = p.page(1) >>> page1 >>> 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 .. note:: Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``, or any other object with a ``count()`` or ``__len__()`` method. When determining the number of objects contained in the passed object, ``Paginator`` will first try calling ``count()``, then fallback to using ``len()`` if the passed object has no ``count()`` method. This allows objects such as Django's ``QuerySet`` to use a more efficient ``count()`` method when available. Paginating a ``ListView`` ========================= :class:`django.views.generic.list.ListView` provides a builtin way to paginate the displayed list. You can do this by adding :attr:`~django.views.generic.list.MultipleObjectMixin.paginate_by` attribute to your view class, for example:: from django.views.generic import ListView from myapp.models import Contacts class ContactsList(ListView): paginate_by = 2 model = Contacts The only thing your users will be missing is a way to navigate to the next or previous page. To achieve this, add links to the next and previous page, like shown in the below example ``list.html``. .. _using-paginator-in-view: Using ``Paginator`` in a view ============================= Here's a slightly more complex example using :class:`~django.core.paginator.Paginator` in a view to paginate a queryset. We give both the view and the accompanying template to show how you can display the results. This example assumes you have a ``Contacts`` model that has already been imported. The view function looks like this:: from django.core.paginator import Paginator from django.shortcuts import render def listing(request): contact_list = Contacts.objects.all() paginator = Paginator(contact_list, 25) # Show 25 contacts per page page = request.GET.get('page') contacts = paginator.get_page(page) return render(request, 'list.html', {'contacts': contacts}) In the template :file:`list.html`, you'll want to include navigation between pages along with any interesting information from the objects themselves: .. code-block:: html+django {% for contact in contacts %} {# Each "contact" is a Contact model object. #} {{ contact.full_name|upper }}
... {% endfor %}