Author: russellm
Date: 2010-12-04 22:32:36 -0600 (Sat, 04 Dec 2010)
New Revision: 14828

Modified:
   django/trunk/django/views/generic/list.py
   django/trunk/docs/ref/class-based-views.txt
   django/trunk/tests/regressiontests/generic_views/list.py
   django/trunk/tests/regressiontests/generic_views/urls.py
   django/trunk/tests/regressiontests/generic_views/views.py
Log:
Fixed #14773 -- Modified MultipleObjectMixin to allow for custom paginators. 
Thanks to piquadrat for the report and initial patch.

Modified: django/trunk/django/views/generic/list.py
===================================================================
--- django/trunk/django/views/generic/list.py   2010-12-05 02:09:29 UTC (rev 
14827)
+++ django/trunk/django/views/generic/list.py   2010-12-05 04:32:36 UTC (rev 
14828)
@@ -10,6 +10,7 @@
     model = None
     paginate_by = None
     context_object_name = None
+    paginator_class = Paginator
 
     def get_queryset(self):
         """
@@ -32,7 +33,7 @@
         Paginate the queryset, if needed.
         """
         if queryset.count() > page_size:
-            paginator = Paginator(queryset, page_size, 
allow_empty_first_page=self.get_allow_empty())
+            paginator = self.get_paginator(queryset, page_size, 
allow_empty_first_page=self.get_allow_empty())
             page = self.kwargs.get('page', None) or 
self.request.GET.get('page', 1)
             try:
                 page_number = int(page)
@@ -55,6 +56,12 @@
         """
         return self.paginate_by
 
+    def get_paginator(self, queryset, per_page, orphans=0, 
allow_empty_first_page=True):
+        """
+        Return an instance of the paginator for this view.
+        """
+        return self.paginator_class(queryset, per_page, orphans=orphans, 
allow_empty_first_page=allow_empty_first_page)
+
     def get_allow_empty(self):
         """
         Returns ``True`` if the view should display empty lists, and ``False``

Modified: django/trunk/docs/ref/class-based-views.txt
===================================================================
--- django/trunk/docs/ref/class-based-views.txt 2010-12-05 02:09:29 UTC (rev 
14827)
+++ django/trunk/docs/ref/class-based-views.txt 2010-12-05 04:32:36 UTC (rev 
14828)
@@ -305,6 +305,14 @@
         expect either a ``page`` query string parameter (via ``GET``) or a
         ``page`` variable specified in the URLconf.
 
+    .. attribute:: paginator_class
+
+       The paginator class to be used for pagination. By default,
+       :class:`django.core.paginator.Paginator` is used. If the custom 
paginator
+       class doesn't have the same constructor interface as
+       :class:`django.core.paginator.Paginator`, you will also need to
+       provide an implementation for :meth:`MultipleObjectMixin.get_paginator`.
+
     .. attribute:: context_object_name
 
         Designates the name of the variable to use in the context.
@@ -329,6 +337,11 @@
         pagination. By default this simply returns the value of
         :attr:`MultipleObjectMixin.paginate_by`.
 
+    .. method:: get_paginator(queryset, queryset, per_page, orphans=0, 
allow_empty_first_page=True)
+
+        Returns an instance of the paginator to use for this view. By default,
+        instantiates an instance of :attr:`paginator_class`.
+
     .. method:: get_allow_empty()
 
         Return a boolean specifying whether to display the page if no objects

Modified: django/trunk/tests/regressiontests/generic_views/list.py
===================================================================
--- django/trunk/tests/regressiontests/generic_views/list.py    2010-12-05 
02:09:29 UTC (rev 14827)
+++ django/trunk/tests/regressiontests/generic_views/list.py    2010-12-05 
04:32:36 UTC (rev 14828)
@@ -2,8 +2,8 @@
 from django.test import TestCase
 
 from regressiontests.generic_views.models import Author
+from regressiontests.generic_views.views import CustomPaginator
 
-
 class ListViewTests(TestCase):
     fixtures = ['generic-views-test-data.json']
     urls = 'regressiontests.generic_views.urls'
@@ -86,6 +86,21 @@
         res = self.client.get('/list/authors/paginated/?page=frog')
         self.assertEqual(res.status_code, 404)
 
+    def test_paginated_custom_paginator_class(self):
+        self._make_authors(7)
+        res = self.client.get('/list/authors/paginated/custom_class/')
+        self.assertEqual(res.status_code, 200)
+        self.assertIsInstance(res.context['paginator'], CustomPaginator)
+        # Custom pagination allows for 2 orphans on a page size of 5
+        self.assertEqual(len(res.context['object_list']), 7)
+
+    def test_paginated_custom_paginator_constructor(self):
+        self._make_authors(7)
+        res = self.client.get('/list/authors/paginated/custom_constructor/')
+        self.assertEqual(res.status_code, 200)
+        # Custom pagination allows for 2 orphans on a page size of 5
+        self.assertEqual(len(res.context['object_list']), 7)
+
     def test_allow_empty_false(self):
         res = self.client.get('/list/authors/notempty/')
         self.assertEqual(res.status_code, 200)

Modified: django/trunk/tests/regressiontests/generic_views/urls.py
===================================================================
--- django/trunk/tests/regressiontests/generic_views/urls.py    2010-12-05 
02:09:29 UTC (rev 14827)
+++ django/trunk/tests/regressiontests/generic_views/urls.py    2010-12-05 
04:32:36 UTC (rev 14828)
@@ -117,6 +117,10 @@
         views.AuthorList.as_view(context_object_name='object_list')),
     (r'^list/authors/invalid/$',
         views.AuthorList.as_view(queryset=None)),
+    (r'^list/authors/paginated/custom_class/$',
+        views.AuthorList.as_view(paginate_by=5, 
paginator_class=views.CustomPaginator)),
+    (r'^list/authors/paginated/custom_constructor/$',
+        views.AuthorListCustomPaginator.as_view()),
 
     # YearArchiveView
     # Mixing keyword and possitional captures below is intentional; the views

Modified: django/trunk/tests/regressiontests/generic_views/views.py
===================================================================
--- django/trunk/tests/regressiontests/generic_views/views.py   2010-12-05 
02:09:29 UTC (rev 14827)
+++ django/trunk/tests/regressiontests/generic_views/views.py   2010-12-05 
04:32:36 UTC (rev 14828)
@@ -1,4 +1,5 @@
 from django.contrib.auth.decorators import login_required
+from django.core.paginator import Paginator
 from django.core.urlresolvers import reverse
 from django.utils.decorators import method_decorator
 from django.views import generic
@@ -50,7 +51,24 @@
     queryset = Author.objects.all()
 
 
+class CustomPaginator(Paginator):
+    def __init__(self, queryset, page_size, orphans=0, 
allow_empty_first_page=True):
+        super(CustomPaginator, self).__init__(
+            queryset,
+            page_size,
+            orphans=2,
+            allow_empty_first_page=allow_empty_first_page)
 
+class AuthorListCustomPaginator(AuthorList):
+    paginate_by = 5;
+
+    def get_paginator(self, queryset, page_size, orphans=0, 
allow_empty_first_page=True):
+        return super(AuthorListCustomPaginator, self).get_paginator(
+            queryset,
+            page_size,
+            orphans=2,
+            allow_empty_first_page=allow_empty_first_page)
+
 class ArtistCreate(generic.CreateView):
     model = Artist
 

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-upda...@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to