PageRenderTime 37ms CodeModel.GetById 30ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 1ms

/docs/topics/pagination.txt

https://code.google.com/p/mango-py/
Plain Text | 283 lines | 201 code | 82 blank | 0 comment | 0 complexity | 79991a683c1753e0bb16340af59f826a MD5 | raw file
  1==========
  2Pagination
  3==========
  4
  5.. module:: django.core.paginator
  6   :synopsis: Classes to help you easily manage paginated data.
  7
  8Django provides a few classes that help you manage paginated data -- that is,
  9data that's split across several pages, with "Previous/Next" links. These
 10classes live in :file:`django/core/paginator.py`.
 11
 12Example
 13=======
 14
 15Give :class:`Paginator` a list of objects, plus the number of items you'd like to
 16have on each page, and it gives you methods for accessing the items for each
 17page::
 18
 19    >>> from django.core.paginator import Paginator
 20    >>> objects = ['john', 'paul', 'george', 'ringo']
 21    >>> p = Paginator(objects, 2)
 22
 23    >>> p.count
 24    4
 25    >>> p.num_pages
 26    2
 27    >>> p.page_range
 28    [1, 2]
 29
 30    >>> page1 = p.page(1)
 31    >>> page1
 32    <Page 1 of 2>
 33    >>> page1.object_list
 34    ['john', 'paul']
 35
 36    >>> page2 = p.page(2)
 37    >>> page2.object_list
 38    ['george', 'ringo']
 39    >>> page2.has_next()
 40    False
 41    >>> page2.has_previous()
 42    True
 43    >>> page2.has_other_pages()
 44    True
 45    >>> page2.next_page_number()
 46    3
 47    >>> page2.previous_page_number()
 48    1
 49    >>> page2.start_index() # The 1-based index of the first item on this page
 50    3
 51    >>> page2.end_index() # The 1-based index of the last item on this page
 52    4
 53
 54    >>> p.page(0)
 55    Traceback (most recent call last):
 56    ...
 57    EmptyPage: That page number is less than 1
 58    >>> p.page(3)
 59    Traceback (most recent call last):
 60    ...
 61    EmptyPage: That page contains no results
 62
 63.. note::
 64
 65    Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``,
 66    or any other object with a ``count()`` or ``__len__()`` method. When
 67    determining the number of objects contained in the passed object,
 68    ``Paginator`` will first try calling ``count()``, then fallback to using
 69    ``len()`` if the passed object has no ``count()`` method. This allows
 70    objects such as Django's ``QuerySet`` to use a more efficient ``count()``
 71    method when available.
 72
 73
 74Using ``Paginator`` in a view
 75==============================
 76
 77Here's a slightly more complex example using :class:`Paginator` in a view to
 78paginate a queryset. We give both the view and the accompanying template to
 79show how you can display the results. This example assumes you have a
 80``Contacts`` model that has already been imported.
 81
 82The view function looks like this::
 83
 84    from django.core.paginator import Paginator, InvalidPage, EmptyPage
 85
 86    def listing(request):
 87        contact_list = Contacts.objects.all()
 88        paginator = Paginator(contact_list, 25) # Show 25 contacts per page
 89
 90        # Make sure page request is an int. If not, deliver first page.
 91        try:
 92            page = int(request.GET.get('page', '1'))
 93        except ValueError:
 94            page = 1
 95
 96        # If page request (9999) is out of range, deliver last page of results.
 97        try:
 98            contacts = paginator.page(page)
 99        except (EmptyPage, InvalidPage):
100            contacts = paginator.page(paginator.num_pages)
101
102        return render_to_response('list.html', {"contacts": contacts})
103
104In the template :file:`list.html`, you'll want to include navigation between
105pages along with any interesting information from the objects themselves::
106
107    {% for contact in contacts.object_list %}
108        {# Each "contact" is a Contact model object. #}
109        {{ contact.full_name|upper }}<br />
110        ...
111    {% endfor %}
112
113    <div class="pagination">
114        <span class="step-links">
115            {% if contacts.has_previous %}
116                <a href="?page={{ contacts.previous_page_number }}">previous</a>
117            {% endif %}
118
119            <span class="current">
120                Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
121            </span>
122
123            {% if contacts.has_next %}
124                <a href="?page={{ contacts.next_page_number }}">next</a>
125            {% endif %}
126        </span>
127    </div>
128
129
130``Paginator`` objects
131=====================
132
133The :class:`Paginator` class has this constructor:
134
135.. class:: Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
136
137Required arguments
138------------------
139
140``object_list``
141    A list, tuple, Django ``QuerySet``, or other sliceable object with a
142    ``count()`` or ``__len__()`` method.
143
144``per_page``
145    The maximum number of items to include on a page, not including orphans
146    (see the ``orphans`` optional argument below).
147
148Optional arguments
149------------------
150
151``orphans``
152    The minimum number of items allowed on the last page, defaults to zero.
153    Use this when you don't want to have a last page with very few items.
154    If the last page would normally have a number of items less than or equal
155    to ``orphans``, then those items will be added to the previous page (which
156    becomes the last page) instead of leaving the items on a page by
157    themselves. For example, with 23 items, ``per_page=10``, and
158    ``orphans=3``, there will be two pages; the first page with 10 items and
159    the  second (and last) page with 13 items.
160
161``allow_empty_first_page``
162    Whether or not the first page is allowed to be empty.  If ``False`` and
163    ``object_list`` is  empty, then an ``EmptyPage`` error will be raised.
164
165Methods
166-------
167
168.. method:: Paginator.page(number)
169
170    Returns a :class:`Page` object with the given 1-based index. Raises
171    :exc:`InvalidPage` if the given page number doesn't exist.
172
173Attributes
174----------
175
176.. attribute:: Paginator.count
177
178    The total number of objects, across all pages.
179
180    .. note::
181
182        When determining the number of objects contained in ``object_list``,
183        ``Paginator`` will first try calling ``object_list.count()``. If
184        ``object_list`` has no ``count()`` method, then ``Paginator`` will
185        fallback to using ``len(object_list)``. This allows objects, such as
186        Django's ``QuerySet``, to use a more efficient ``count()`` method when
187        available.
188
189.. attribute:: Paginator.num_pages
190
191    The total number of pages.
192
193.. attribute:: Paginator.page_range
194
195    A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
196
197``InvalidPage`` exceptions
198==========================
199
200.. exception:: InvalidPage
201
202	A base class for exceptions raised when a paginator is passed an invalid
203	page number.
204
205The :meth:`Paginator.page` method raises an exception if the requested page is
206invalid (i.e., not an integer) or contains no objects. Generally, it's enough
207to trap the ``InvalidPage`` exception, but if you'd like more granularity, you
208can trap either of the following exceptions:
209
210.. exception:: PageNotAnInteger
211
212    Raised when ``page()`` is given a value that isn't an integer.
213
214.. exception:: EmptyPage
215
216    Raised when ``page()`` is given a valid value but no objects exist on that
217    page.
218
219Both of the exceptions are subclasses of :exc:`InvalidPage`, so you can handle
220them both with a simple ``except InvalidPage``.
221
222
223``Page`` objects
224================
225
226You usually won't construct ``Page`` objects by hand -- you'll get them
227using :meth:`Paginator.page`.
228
229.. class:: Page(object_list, number, paginator)
230
231Methods
232-------
233
234.. method:: Page.has_next()
235
236    Returns ``True`` if there's a next page.
237
238.. method:: Page.has_previous()
239
240    Returns ``True`` if there's a previous page.
241
242.. method:: Page.has_other_pages()
243
244    Returns ``True`` if there's a next *or* previous page.
245
246.. method:: Page.next_page_number()
247
248    Returns the next page number. Note that this is "dumb" and will return the
249    next page number regardless of whether a subsequent page exists.
250
251.. method:: Page.previous_page_number()
252
253    Returns the previous page number. Note that this is "dumb" and will return
254    the previous page number regardless of whether a previous page exists.
255
256.. method:: Page.start_index()
257
258    Returns the 1-based index of the first object on the page, relative to all
259    of the objects in the paginator's list. For example, when paginating a list
260    of 5 objects with 2 objects per page, the second page's
261    :meth:`~Page.start_index` would return ``3``.
262
263.. method:: Page.end_index()
264
265    Returns the 1-based index of the last object on the page, relative to all
266    of the objects in the paginator's list. For example, when paginating a list
267    of 5 objects with 2 objects per page, the second page's
268    :meth:`~Page.end_index` would return ``4``.
269
270Attributes
271----------
272
273.. attribute:: Page.object_list
274
275    The list of objects on this page.
276
277.. attribute:: Page.number
278
279    The 1-based page number for this page.
280
281.. attribute:: Page.paginator
282
283    The associated :class:`Paginator` object.