Django

Code

Changeset 8121

Show
Ignore:
Timestamp:
07/27/08 18:01:55 (4 months ago)
Author:
gwilson
Message:

Made the Paginator class a bit more backwards compatible with the lecacy ObjectPaginator class by using the ObjectPaginator's _get_count method. Instead of explicitly checking for an instance of QuerySet, this now allows any object with a count() or __len__() method defined to be passed to Paginator. For one, this is useful when you have custom QuerySet-like classes that implement a count() method but don't inherit from QuerySet explicitly.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/paginator.py

    r7867 r8121  
    4343        "Returns the total number of objects, across all pages." 
    4444        if self._count is None: 
    45             from django.db.models.query import QuerySet 
    46             if isinstance(self.object_list, QuerySet): 
     45            try: 
    4746                self._count = self.object_list.count() 
    48             else: 
     47            except (AttributeError, TypeError): 
     48                # AttributeError if object_list has no count() method. 
     49                # TypeError if object_list.count() requires arguments 
     50                # (i.e. is of type list). 
    4951                self._count = len(self.object_list) 
    5052        return self._count 
     
    170172        return page_number * self.num_per_page 
    171173 
    172     def _get_count(self): 
    173         # The old API allowed for self.object_list to be either a QuerySet or a 
    174         # list. Here, we handle both. 
    175         if self._count is None: 
    176             try: 
    177                 self._count = self.object_list.count() 
    178             except (AttributeError, TypeError): 
    179                 # AttributeError if object_list has no count() method. 
    180                 # TypeError if object_list.count() requires arguments 
    181                 # (i.e. is of type list). 
    182                 self._count = len(self.object_list) 
    183         return self._count 
    184     count = property(_get_count) 
    185  
    186174    # The old API called it "hits" instead of "count". 
    187     hits = count 
     175    hits = Paginator.count 
    188176 
    189177    # The old API called it "pages" instead of "num_pages". 
  • django/trunk/docs/pagination.txt

    r7867 r8121  
    6060    InvalidPage 
    6161 
    62 Note that you can give ``Paginator`` a list/tuple or a Django ``QuerySet``. The 
    63 only difference is in implementation; if you pass a ``QuerySet``, the 
    64 ``Paginator`` will call its ``count()`` method instead of using ``len()``, 
    65 because the former is more efficient. 
     62Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``, or 
     63any other object with a ``count()`` or ``__len__()`` method. When determining 
     64the number of objects contained in the passed object, ``Paginator`` will first 
     65try calling ``count()``, then fallback to using ``len()`` if the passed object 
     66has no ``count()`` method. This allows objects such as Django's ``QuerySet`` to 
     67use a more efficient ``count()`` method when available. 
    6668 
    6769``Paginator`` objects 
  • django/trunk/tests/modeltests/pagination/models.py

    r8114 r8121  
    1411415 
    142142 
     143# Paginator can be passed other objects with a count() method. 
     144>>> class CountContainer: 
     145...     def count(self): 
     146...         return 42 
     147>>> paginator = Paginator(CountContainer(), 10) 
     148>>> paginator.count 
     14942 
     150>>> paginator.num_pages 
     1515 
     152>>> paginator.page_range 
     153[1, 2, 3, 4, 5] 
     154 
     155# Paginator can be passed other objects that implement __len__. 
     156>>> class LenContainer: 
     157...     def __len__(self): 
     158...         return 42 
     159>>> paginator = Paginator(LenContainer(), 10) 
     160>>> paginator.count 
     16142 
     162>>> paginator.num_pages 
     1635 
     164>>> paginator.page_range 
     165[1, 2, 3, 4, 5] 
     166 
     167 
    143168################################ 
    144169# Legacy API (ObjectPaginator) #