pagination.txt 8.5 KB
Newer Older
1 2 3 4
==========
Pagination
==========

5 6 7
.. module:: django.core.paginator
   :synopsis: Classes to help you easily manage paginated data.

8 9
Django provides a few classes that help you manage paginated data -- that is,
data that's split across several pages, with "Previous/Next" links. These
10
classes live in :file:`django/core/paginator.py`.
11 12 13 14

Example
=======

15
Give :class:`Paginator` a list of objects, plus the number of items you'd like to
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
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
    >>> 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()
46 47 48
    Traceback (most recent call last):
    ...
    EmptyPage: That page contains no results
49 50 51 52 53 54 55 56 57 58
    >>> 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):
    ...
59
    EmptyPage: That page number is less than 1
60 61 62
    >>> p.page(3)
    Traceback (most recent call last):
    ...
63 64 65
    EmptyPage: That page contains no results

.. note::
66

67 68
    Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``,
    or any other object with a ``count()`` or ``__len__()`` method. When
69 70 71 72 73 74
    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.

75 76 77 78 79 80 81 82 83 84 85

Using ``Paginator`` in a view
==============================

Here's a slightly more complex example using :class:`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::

86
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
87 88 89 90 91

    def listing(request):
        contact_list = Contacts.objects.all()
        paginator = Paginator(contact_list, 25) # Show 25 contacts per page

92
        page = request.GET.get('page')
93 94
        try:
            contacts = paginator.page(page)
95 96 97 98 99
        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.
100 101 102 103 104 105 106
            contacts = paginator.page(paginator.num_pages)

        return render_to_response('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::

107
    {% for contact in contacts %}
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
        {# 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>

129 130 131
``Paginator`` objects
=====================

132 133 134 135
The :class:`Paginator` class has this constructor:

.. class:: Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)

136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
Required arguments
------------------

``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).

Optional arguments
------------------

``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
162
    ``object_list`` is  empty, then an ``EmptyPage`` error will be raised.
163

164 165 166
Methods
-------

167
.. method:: Paginator.page(number)
168

169 170
    Returns a :class:`Page` object with the given 1-based index. Raises
    :exc:`InvalidPage` if the given page number doesn't exist.
171 172 173 174

Attributes
----------

175
.. attribute:: Paginator.count
176

177
    The total number of objects, across all pages.
178 179

    .. note::
180 181 182 183

        When determining the number of objects contained in ``object_list``,
        ``Paginator`` will first try calling ``object_list.count()``. If
        ``object_list`` has no ``count()`` method, then ``Paginator`` will
184 185 186
        fallback to using ``len(object_list)``. This allows objects, such as
        Django's ``QuerySet``, to use a more efficient ``count()`` method when
        available.
187

188
.. attribute:: Paginator.num_pages
189

190
    The total number of pages.
191

192
.. attribute:: Paginator.page_range
193

194
    A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
195

196

197 198 199
``InvalidPage`` exceptions
==========================

200 201
.. exception:: InvalidPage

202 203
    A base class for exceptions raised when a paginator is passed an invalid
    page number.
204 205 206 207 208 209 210

The :meth:`Paginator.page` method raises an exception if the requested page is
invalid (i.e., not an integer) or contains no objects. Generally, it's enough
to trap the ``InvalidPage`` exception, but if you'd like more granularity, you
can trap either of the following exceptions:

.. exception:: PageNotAnInteger
211

212
    Raised when ``page()`` is given a value that isn't an integer.
213

214 215
.. exception:: EmptyPage

216 217
    Raised when ``page()`` is given a valid value but no objects exist on that
    page.
218

219
Both of the exceptions are subclasses of :exc:`InvalidPage`, so you can handle
220 221
them both with a simple ``except InvalidPage``.

222

223 224 225
``Page`` objects
================

226
You usually won't construct ``Page`` objects by hand -- you'll get them
227 228
using :meth:`Paginator.page`.

229 230
.. class:: Page(object_list, number, paginator)

231 232
    A page acts like a sequence of :attr:`Page.object_list` when using
    ``len()`` or iterating it directly.
233

234 235 236
Methods
-------

237
.. method:: Page.has_next()
238

239
    Returns ``True`` if there's a next page.
240

241
.. method:: Page.has_previous()
242

243
    Returns ``True`` if there's a previous page.
244

245
.. method:: Page.has_other_pages()
246

247
    Returns ``True`` if there's a next *or* previous page.
248

249
.. method:: Page.next_page_number()
250

251 252 253 254 255
    Returns the next page number.

    .. versionchanged:: 1.5

    Raises :exc:`InvalidPage` if next page doesn't exist.
256

257
.. method:: Page.previous_page_number()
258

259 260 261 262 263
    Returns the previous page number.

    .. versionchanged:: 1.5

    Raises :exc:`InvalidPage` if previous page doesn't exist.
264

265
.. method:: Page.start_index()
266

267 268
    Returns the 1-based index of the first object on the page, relative to all
    of the objects in the paginator's list. For example, when paginating a list
269 270
    of 5 objects with 2 objects per page, the second page's
    :meth:`~Page.start_index` would return ``3``.
271

272
.. method:: Page.end_index()
273

274 275 276 277
    Returns the 1-based index of the last object on the page, relative to all
    of the objects in the paginator's list. For example, when paginating a list
    of 5 objects with 2 objects per page, the second page's
    :meth:`~Page.end_index` would return ``4``.
278 279 280 281

Attributes
----------

282
.. attribute:: Page.object_list
283

284
    The list of objects on this page.
285

286
.. attribute:: Page.number
287

288
    The 1-based page number for this page.
289

290
.. attribute:: Page.paginator
291

292
    The associated :class:`Paginator` object.