Ticket #11596: 11596.3.diff

File 11596.3.diff, 3.4 KB (added by Chris Beaven, 14 years ago)

with docs

  • django/core/paginator.py

    diff --git a/django/core/paginator.py b/django/core/paginator.py
    index 495cdf2..479cb49 100644
    a b  
    11from math import ceil
     2import collections
    23
    34class InvalidPage(Exception):
    45    pass
    class Paginator(object):  
    7576
    7677QuerySetPaginator = Paginator # For backwards-compatibility.
    7778
    78 class Page(object):
     79class Page(collections.Sequence):
    7980    def __init__(self, object_list, number, paginator):
    8081        self.object_list = object_list
    8182        self.number = number
    class Page(object):  
    8485    def __repr__(self):
    8586        return '<Page %s of %s>' % (self.number, self.paginator.num_pages)
    8687
     88    def __len__(self):
     89        return len(self.object_list)
     90
     91    def __getitem__(self, index):
     92        # The object_list is converted to a list so that if it was a QuerySet
     93        # it won't be a database hit per __getitem__.
     94        return list(self.object_list)[index]
     95
    8796    def has_next(self):
    8897        return self.number < self.paginator.num_pages
    8998
  • docs/topics/pagination.txt

    diff --git a/docs/topics/pagination.txt b/docs/topics/pagination.txt
    index db776aa..197b61b 100644
    a b The view function looks like this::  
    104104In the template :file:`list.html`, you'll want to include navigation between
    105105pages along with any interesting information from the objects themselves::
    106106
    107     {% for contact in contacts.object_list %}
     107    {% for contact in contacts %}
    108108        {# Each "contact" is a Contact model object. #}
    109109        {{ contact.full_name|upper }}<br />
    110110        ...
    pages along with any interesting information from the objects themselves::  
    126126        </span>
    127127    </div>
    128128
     129.. versionchanged:: 1.3
     130    Previously, you would need to use
     131    ``{% for contact in contacts.object_list %}``, since the ``Page``
     132    object was not iterable.
     133
    129134
    130135``Paginator`` objects
    131136=====================
    Attributes  
    194199
    195200    A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
    196201
     202
    197203``InvalidPage`` exceptions
    198204==========================
    199205
    them both with a simple ``except InvalidPage``.  
    221227You usually won't construct :class:`Pages <Page>` by hand -- you'll get them
    222228using :meth:`Paginator.page`.
    223229
     230.. versionadded:: 1.3
     231    A page acts like a sequence of :attr:`Page.object_list` when using
     232    ``len()`` or iterating it directly.
    224233
    225234Methods
    226235-------
  • tests/regressiontests/pagination_regress/tests.py

    diff --git a/tests/regressiontests/pagination_regress/tests.py b/tests/regressiontests/pagination_regress/tests.py
    index 28fe316..1cddd43 100644
    a b class PaginatorTests(TestCase):  
    154154        self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 0, False), 1, None)
    155155        self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 1, False), 1, None)
    156156        self.assertRaises(EmptyPage, self.check_indexes, ([], 4, 2, False), 1, None)
     157
     158    def test_page_sequence(self):
     159        """
     160        Tests that a paginator page acts like a standard sequence.
     161        """
     162        eleven = 'abcdefghijk'
     163        page2 = Paginator(eleven, per_page=5, orphans=1).page(2)
     164        self.assertEqual(len(page2), 6)
     165        self.assertTrue('k' in page2)
     166        self.assertFalse('a' in page2)
     167        self.assertEqual(''.join(page2), 'fghijk')
Back to Top