Ticket #14900: admin-paginator.diff
File admin-paginator.diff, 9.1 KB (added by , 14 years ago) |
---|
-
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 7a42e94..bb11b3d 100644
a b from django.contrib.admin.util import unquote, flatten_fieldsets, get_deleted_ob 9 9 from django.contrib import messages 10 10 from django.views.decorators.csrf import csrf_protect 11 11 from django.core.exceptions import PermissionDenied, ValidationError 12 from django.core.paginator import Paginator 12 13 from django.db import models, transaction, router 13 14 from django.db.models.fields import BLANK_CHOICE_DASH 14 15 from django.http import Http404, HttpResponse, HttpResponseRedirect … … class ModelAdmin(BaseModelAdmin): 215 216 date_hierarchy = None 216 217 save_as = False 217 218 save_on_top = False 219 paginator_class = Paginator 218 220 inlines = [] 219 221 220 222 # Custom templates (designed to be over-ridden in subclasses) … … class ModelAdmin(BaseModelAdmin): 975 977 976 978 ChangeList = self.get_changelist(request) 977 979 try: 978 cl = ChangeList(request, self.model, list_display, self.list_display_links, self.list_filter, 979 self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page, self.list_editable, self) 980 cl = ChangeList(request, self.model, list_display, self.list_display_links, 981 self.list_filter, self.date_hierarchy, self.search_fields, 982 self.list_select_related, self.list_per_page, self.list_editable, self.paginator_class, self) 980 983 except IncorrectLookupParameters: 981 984 # Wacky lookup parameters were given, so redirect to the main 982 985 # changelist page, without parameters, and pass an 'invalid=1' -
django/contrib/admin/views/main.py
diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 606388c..19c7399 100644
a b ERROR_FLAG = 'e' 26 26 EMPTY_CHANGELIST_VALUE = '(None)' 27 27 28 28 class ChangeList(object): 29 def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_editable, model_admin):29 def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_editable, paginator_class, model_admin): 30 30 self.model = model 31 31 self.opts = model._meta 32 32 self.lookup_opts = self.opts … … class ChangeList(object): 40 40 self.list_per_page = list_per_page 41 41 self.list_editable = list_editable 42 42 self.model_admin = model_admin 43 self.paginator_class = paginator_class 43 44 44 45 # Get search parameters from the query string. 45 46 try: … … class ChangeList(object): 94 95 return '?%s' % urlencode(p) 95 96 96 97 def get_results(self, request): 97 paginator = Paginator(self.query_set, self.list_per_page)98 paginator = self.get_paginator(self.query_set, self.list_per_page) 98 99 # Get the number of objects, with admin filters applied. 99 100 result_count = paginator.count 100 101 … … class ChangeList(object): 244 245 245 246 def url_for_result(self, result): 246 247 return "%s/" % quote(getattr(result, self.pk_attname)) 248 249 def get_paginator(self, queryset, per_page, orphans=0, allow_empty_first_page=True): 250 return self.paginator_class(queryset, per_page, orphans, allow_empty_first_page) -
docs/ref/contrib/admin/index.txt
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index 9928118..cb07cb6 100644
a b subclass:: 516 516 Django will only honor the first element in the list/tuple; any others 517 517 will be ignored. 518 518 519 .. attribute:: ModelAdmin.paginator_class 520 521 .. versionadded:: 1.3 522 523 The paginator class to be used for pagination. By default, 524 :class:`django.core.paginator.Paginator` is used. If the custom paginator 525 class doesn't have the same constructor interface as 526 :class:`django.core.paginator.Paginator`, you will also need to 527 provide an implementation for :meth:`MultipleObjectMixin.get_paginator`. 528 519 529 .. attribute:: ModelAdmin.prepopulated_fields 520 530 521 531 Set ``prepopulated_fields`` to a dictionary mapping field names to the … … templates used by the :class:`ModelAdmin` views: 945 955 using the :mod:`django.contrib.messages` backend. See the 946 956 :ref:`custom ModelAdmin example <custom-admin-action>`. 947 957 958 .. method:: ModelAdmin.get_paginator(queryset, per_page, orphans=0, allow_empty_first_page=True) 959 960 .. versionadded:: 1.3 961 962 Returns an instance of the paginator to use for this view. By default, 963 instantiates an instance of :attr:`paginator_class`. 964 948 965 Other methods 949 966 ~~~~~~~~~~~~~ 950 967 -
tests/regressiontests/admin_changelist/tests.py
diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py index 96b36f8..b94a79b 100644
a b 1 1 from django.contrib import admin 2 2 from django.contrib.admin.options import IncorrectLookupParameters 3 3 from django.contrib.admin.views.main import ChangeList 4 from django.core.paginator import Paginator 4 5 from django.template import Context, Template 5 6 from django.test import TransactionTestCase 7 6 8 from regressiontests.admin_changelist.models import Child, Parent 7 9 10 8 11 class ChangeListTests(TransactionTestCase): 9 12 def test_select_related_preserved(self): 10 13 """ … … class ChangeListTests(TransactionTestCase): 14 17 m = ChildAdmin(Child, admin.site) 15 18 cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links, 16 19 m.list_filter, m.date_hierarchy, m.search_fields, 17 m.list_select_related, m.list_per_page, m.list_editable, m) 20 m.list_select_related, m.list_per_page, m.list_editable, 21 m.paginator_class, m) 18 22 self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}}) 19 23 20 24 def test_result_list_html(self): … … class ChangeListTests(TransactionTestCase): 28 32 m = ChildAdmin(Child, admin.site) 29 33 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 30 34 m.list_filter, m.date_hierarchy, m.search_fields, 31 m.list_select_related, m.list_per_page, m.list_editable, m) 35 m.list_select_related, m.list_per_page, m.list_editable, 36 m.paginator_class, m) 32 37 cl.formset = None 33 38 template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') 34 39 context = Context({'cl': cl}) … … class ChangeListTests(TransactionTestCase): 57 62 m.list_editable = ['name'] 58 63 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 59 64 m.list_filter, m.date_hierarchy, m.search_fields, 60 m.list_select_related, m.list_per_page, m.list_editable, m) 65 m.list_select_related, m.list_per_page, m.list_editable, 66 m.paginator_class, m) 61 67 FormSet = m.get_changelist_formset(request) 62 68 cl.formset = FormSet(queryset=cl.result_list) 63 69 template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}') … … class ChangeListTests(TransactionTestCase): 91 97 self.assertRaises(IncorrectLookupParameters, lambda: \ 92 98 ChangeList(request, Child, m.list_display, m.list_display_links, 93 99 m.list_filter, m.date_hierarchy, m.search_fields, 94 m.list_select_related, m.list_per_page, m.list_editable, m)) 100 m.list_select_related, m.list_per_page, m.list_editable, 101 m.paginator_class, m)) 102 103 def test_custom_paginator(self): 104 new_parent = Parent.objects.create(name='parent') 105 for i in range(200): 106 new_child = Child.objects.create(name='name %s' % i, parent=new_parent) 107 108 request = MockRequest() 109 m = ChildAdmin(Child, admin.site) 110 m.list_display = ['id', 'name', 'parent'] 111 m.list_display_links = ['id'] 112 m.list_editable = ['name'] 113 m.paginator_class = CustomPaginator 114 115 cl = ChangeList(request, Child, m.list_display, m.list_display_links, 116 m.list_filter, m.date_hierarchy, m.search_fields, 117 m.list_select_related, m.list_per_page, m.list_editable, 118 m.paginator_class, m) 119 120 cl.get_results(request) 121 self.assertIsInstance(cl.paginator, CustomPaginator) 95 122 96 123 97 124 class ChildAdmin(admin.ModelAdmin): … … class ChildAdmin(admin.ModelAdmin): 99 126 def queryset(self, request): 100 127 return super(ChildAdmin, self).queryset(request).select_related("parent__name") 101 128 129 102 130 class MockRequest(object): 103 131 GET = {} 132 133 134 class CustomPaginator(Paginator): 135 def __init__(self, queryset, page_size, orphans=0, allow_empty_first_page=True): 136 super(CustomPaginator, self).__init__( 137 queryset, 138 5, 139 orphans=2, 140 allow_empty_first_page=allow_empty_first_page)