diff --git a/django/views/generic/list.py b/django/views/generic/list.py
index ef90d75..eaa06a8 100644
a
|
b
|
class MultipleObjectMixin(object):
|
10 | 10 | model = None |
11 | 11 | paginate_by = None |
12 | 12 | context_object_name = None |
| 13 | paginator_class = Paginator |
13 | 14 | |
14 | 15 | def get_queryset(self): |
15 | 16 | """ |
… |
… |
class MultipleObjectMixin(object):
|
32 | 33 | Paginate the queryset, if needed. |
33 | 34 | """ |
34 | 35 | if queryset.count() > page_size: |
35 | | paginator = Paginator(queryset, page_size, allow_empty_first_page=self.get_allow_empty()) |
| 36 | paginator = self.paginator_class(queryset, page_size, allow_empty_first_page=self.get_allow_empty()) |
36 | 37 | page = self.kwargs.get('page', None) or self.request.GET.get('page', 1) |
37 | 38 | try: |
38 | 39 | page_number = int(page) |
diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt
index ada25a6..9609b76 100644
a
|
b
|
MultipleObjectMixin
|
305 | 305 | expect either a ``page`` query string parameter (via ``GET``) or a |
306 | 306 | ``page`` variable specified in the URLconf. |
307 | 307 | |
| 308 | .. attribute:: paginator_class |
| 309 | |
| 310 | The paginator class to be used for pagination. By default, |
| 311 | :class:`django.core.paginator.Paginator` is used. Custom paginator classes have to conform to |
| 312 | the interface defined by that class. |
| 313 | |
308 | 314 | .. attribute:: context_object_name |
309 | 315 | |
310 | 316 | Designates the name of the variable to use in the context. |
diff --git a/tests/regressiontests/generic_views/list.py b/tests/regressiontests/generic_views/list.py
index 8f6af74..622fc06 100644
a
|
b
|
from django.core.exceptions import ImproperlyConfigured
|
2 | 2 | from django.test import TestCase |
3 | 3 | |
4 | 4 | from regressiontests.generic_views.models import Author |
5 | | |
| 5 | from regressiontests.generic_views.views import CustomPaginator |
6 | 6 | |
7 | 7 | class ListViewTests(TestCase): |
8 | 8 | fixtures = ['generic-views-test-data.json'] |
… |
… |
class ListViewTests(TestCase):
|
85 | 85 | self._make_authors(100) |
86 | 86 | res = self.client.get('/list/authors/paginated/?page=frog') |
87 | 87 | self.assertEqual(res.status_code, 404) |
| 88 | |
| 89 | def test_paginated_custom_paginator(self): |
| 90 | self._make_authors(10) |
| 91 | res = self.client.get('/list/authors/paginated/custom/') |
| 92 | self.assertIs(res.context['paginator'].__class__, CustomPaginator) |
88 | 93 | |
89 | 94 | def test_allow_empty_false(self): |
90 | 95 | res = self.client.get('/list/authors/notempty/') |
diff --git a/tests/regressiontests/generic_views/urls.py b/tests/regressiontests/generic_views/urls.py
index 61f0387..8ed9776 100644
a
|
b
|
urlpatterns = patterns('',
|
113 | 113 | views.AuthorList.as_view(context_object_name='object_list')), |
114 | 114 | (r'^list/authors/invalid/$', |
115 | 115 | views.AuthorList.as_view(queryset=None)), |
| 116 | (r'^list/authors/paginated/custom/$', |
| 117 | views.AuthorListCustomPaginator.as_view()), |
116 | 118 | |
117 | 119 | # YearArchiveView |
118 | 120 | # Mixing keyword and possitional captures below is intentional; the views |
diff --git a/tests/regressiontests/generic_views/views.py b/tests/regressiontests/generic_views/views.py
index eacfb71..6d63496 100644
a
|
b
|
|
1 | 1 | from django.contrib.auth.decorators import login_required |
| 2 | from django.core.paginator import Paginator |
2 | 3 | from django.core.urlresolvers import reverse |
3 | 4 | from django.utils.decorators import method_decorator |
4 | 5 | from django.views import generic |
… |
… |
class AuthorList(generic.ListView):
|
50 | 51 | queryset = Author.objects.all() |
51 | 52 | |
52 | 53 | |
| 54 | class CustomPaginator(Paginator): pass |
| 55 | |
| 56 | class AuthorListCustomPaginator(AuthorList): |
| 57 | paginator_class = CustomPaginator |
| 58 | paginate_by = 5 |
| 59 | |
53 | 60 | |
54 | 61 | class ArtistCreate(generic.CreateView): |
55 | 62 | model = Artist |