Ticket #15997: max_show_all_in_model_admin.diff

File max_show_all_in_model_admin.diff, 14.6 KB (added by Jim Dalton, 13 years ago)
  • docs/ref/contrib/admin/index.txt

     
    649649              The ``FieldListFilter`` API is currently considered internal
    650650              and prone to refactoring.
    651651
     652.. attribute:: ModelAdmin.list_max_show_all
     653
     654    .. versionadded:: 1.4
     655
     656    Set ``list_max_show_all`` to control how many items can appear on a "Show
     657    all" admin change list page. The admin will display a "Show all" link on the
     658    change list only if the total result count is less than or equal to this
     659    setting. By default, this is set to ``200``.
     660
    652661.. attribute:: ModelAdmin.list_per_page
    653662
    654663    Set ``list_per_page`` to control how many items appear on each paginated
  • django/contrib/admin/validation.py

     
    9797    if hasattr(cls, 'list_per_page') and not isinstance(cls.list_per_page, int):
    9898        raise ImproperlyConfigured("'%s.list_per_page' should be a integer."
    9999                % cls.__name__)
     100   
     101    # list_max_show_all
     102    if hasattr(cls, 'list_max_show_all') and not isinstance(cls.list_max_show_all, int):
     103        raise ImproperlyConfigured("'%s.list_max_show_all' should be an integer."
     104                % cls.__name__)
    100105
    101106    # list_editable
    102107    if hasattr(cls, 'list_editable') and cls.list_editable:
  • django/contrib/admin/options.py

     
    268268    list_filter = ()
    269269    list_select_related = False
    270270    list_per_page = 100
     271    list_max_show_all = 200
    271272    list_editable = ()
    272273    search_fields = ()
    273274    date_hierarchy = None
     
    10641065        try:
    10651066            cl = ChangeList(request, self.model, list_display, self.list_display_links,
    10661067                self.list_filter, self.date_hierarchy, self.search_fields,
    1067                 self.list_select_related, self.list_per_page, self.list_editable, self)
     1068                self.list_select_related, self.list_per_page, self.list_max_show_all, self.list_editable, self)
    10681069        except IncorrectLookupParameters:
    10691070            # Wacky lookup parameters were given, so redirect to the main
    10701071            # changelist page, without parameters, and pass an 'invalid=1'
  • django/contrib/admin/views/main.py

     
    1111from django.contrib.admin.options import IncorrectLookupParameters
    1212from django.contrib.admin.util import quote, get_fields_from_path
    1313
    14 # The system will display a "Show all" link on the change list only if the
    15 # total result count is less than or equal to this setting.
    16 MAX_SHOW_ALL_ALLOWED = 200
    17 
    1814# Changelist settings
    1915ALL_VAR = 'all'
    2016ORDER_VAR = 'o'
     
    4339class ChangeList(object):
    4440    def __init__(self, request, model, list_display, list_display_links,
    4541            list_filter, date_hierarchy, search_fields, list_select_related,
    46             list_per_page, list_editable, model_admin):
     42            list_per_page, list_max_show_all, list_editable, model_admin):
    4743        self.model = model
    4844        self.opts = model._meta
    4945        self.lookup_opts = self.opts
     
    5551        self.search_fields = search_fields
    5652        self.list_select_related = list_select_related
    5753        self.list_per_page = list_per_page
     54        self.list_max_show_all = list_max_show_all
    5855        self.model_admin = model_admin
    5956
    6057        # Get search parameters from the query string.
     
    144141        else:
    145142            full_result_count = self.root_query_set.count()
    146143
    147         can_show_all = result_count <= MAX_SHOW_ALL_ALLOWED
     144        can_show_all = result_count <= self.list_max_show_all
    148145        multi_page = result_count > self.list_per_page
    149146
    150147        # Get the list of objects to display on this page.
  • tests/regressiontests/admin_filters/tests.py

     
    109109    def get_changelist(self, request, model, modeladmin):
    110110        return ChangeList(request, model, modeladmin.list_display, modeladmin.list_display_links,
    111111            modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
    112             modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_editable, modeladmin)
     112            modeladmin.list_select_related, modeladmin.list_per_page, modeladmin.list_max_show_all, modeladmin.list_editable, modeladmin)
    113113
    114114    def test_datefieldlistfilter(self):
    115115        modeladmin = BookAdmin(Book, site)
  • tests/regressiontests/admin_changelist/tests.py

     
    11from django.contrib import admin
    22from django.contrib.admin.options import IncorrectLookupParameters
    3 from django.contrib.admin.views.main import ChangeList, SEARCH_VAR
     3from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR
    44from django.core.paginator import Paginator
    55from django.template import Context, Template
    66from django.test import TransactionTestCase
     
    1818        m = ChildAdmin(Child, admin.site)
    1919        cl = ChangeList(MockRequest(), Child, m.list_display, m.list_display_links,
    2020                m.list_filter, m.date_hierarchy, m.search_fields,
    21                 m.list_select_related, m.list_per_page, m.list_editable, m)
     21                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    2222        self.assertEqual(cl.query_set.query.select_related, {'parent': {'name': {}}})
    2323
    2424    def test_result_list_empty_changelist_value(self):
     
    3131        m = ChildAdmin(Child, admin.site)
    3232        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    3333                m.list_filter, m.date_hierarchy, m.search_fields,
    34                 m.list_select_related, m.list_per_page, m.list_editable, m)
     34                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    3535        cl.formset = None
    3636        template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
    3737        context = Context({'cl': cl})
     
    5252        m = ChildAdmin(Child, admin.site)
    5353        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    5454                m.list_filter, m.date_hierarchy, m.search_fields,
    55                 m.list_select_related, m.list_per_page, m.list_editable, m)
     55                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    5656        cl.formset = None
    5757        template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
    5858        context = Context({'cl': cl})
     
    8181        m.list_editable = ['name']
    8282        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    8383                m.list_filter, m.date_hierarchy, m.search_fields,
    84                 m.list_select_related, m.list_per_page, m.list_editable, m)
     84                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    8585        FormSet = m.get_changelist_formset(request)
    8686        cl.formset = FormSet(queryset=cl.result_list)
    8787        template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
     
    115115        self.assertRaises(IncorrectLookupParameters, lambda: \
    116116            ChangeList(request, Child, m.list_display, m.list_display_links,
    117117                    m.list_filter, m.date_hierarchy, m.search_fields,
    118                     m.list_select_related, m.list_per_page, m.list_editable, m))
     118                    m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m))
    119119
    120120    def test_custom_paginator(self):
    121121        new_parent = Parent.objects.create(name='parent')
     
    131131
    132132        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    133133                m.list_filter, m.date_hierarchy, m.search_fields,
    134                 m.list_select_related, m.list_per_page, m.list_editable, m)
     134                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    135135
    136136        cl.get_results(request)
    137137        self.assertIsInstance(cl.paginator, CustomPaginator)
     
    153153        cl = ChangeList(request, Band, m.list_display,
    154154                m.list_display_links, m.list_filter, m.date_hierarchy,
    155155                m.search_fields, m.list_select_related, m.list_per_page,
    156                 m.list_editable, m)
     156                m.list_max_show_all, m.list_editable, m)
    157157
    158158        cl.get_results(request)
    159159
     
    176176        cl = ChangeList(request, Group, m.list_display,
    177177                m.list_display_links, m.list_filter, m.date_hierarchy,
    178178                m.search_fields, m.list_select_related, m.list_per_page,
    179                 m.list_editable, m)
     179                m.list_max_show_all, m.list_editable, m)
    180180
    181181        cl.get_results(request)
    182182
     
    200200        cl = ChangeList(request, Quartet, m.list_display,
    201201                m.list_display_links, m.list_filter, m.date_hierarchy,
    202202                m.search_fields, m.list_select_related, m.list_per_page,
    203                 m.list_editable, m)
     203                m.list_max_show_all, m.list_editable, m)
    204204
    205205        cl.get_results(request)
    206206
     
    224224        cl = ChangeList(request, ChordsBand, m.list_display,
    225225                m.list_display_links, m.list_filter, m.date_hierarchy,
    226226                m.search_fields, m.list_select_related, m.list_per_page,
    227                 m.list_editable, m)
     227                m.list_max_show_all, m.list_editable, m)
    228228
    229229        cl.get_results(request)
    230230
     
    247247        cl = ChangeList(request, Parent, m.list_display, m.list_display_links,
    248248                        m.list_filter, m.date_hierarchy, m.search_fields,
    249249                        m.list_select_related, m.list_per_page,
    250                         m.list_editable, m)
     250                        m.list_max_show_all, m.list_editable, m)
    251251
    252252        # Make sure distinct() was called
    253253        self.assertEqual(cl.query_set.count(), 1)
     
    267267        cl = ChangeList(request, Parent, m.list_display, m.list_display_links,
    268268                        m.list_filter, m.date_hierarchy, m.search_fields,
    269269                        m.list_select_related, m.list_per_page,
    270                         m.list_editable, m)
     270                        m.list_max_show_all, m.list_editable, m)
    271271
    272272        # Make sure distinct() was called
    273273        self.assertEqual(cl.query_set.count(), 1)
     
    288288        m = ChildAdmin(Child, admin.site)
    289289        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    290290                m.list_filter, m.date_hierarchy, m.search_fields,
    291                 m.list_select_related, m.list_per_page, m.list_editable, m)
     291                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    292292        self.assertEqual(cl.query_set.count(), 60)
    293293        self.assertEqual(cl.paginator.count, 60)
    294294        self.assertEqual(cl.paginator.page_range, [1, 2, 3, 4, 5, 6])
     
    297297        m = FilteredChildAdmin(Child, admin.site)
    298298        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
    299299                m.list_filter, m.date_hierarchy, m.search_fields,
    300                 m.list_select_related, m.list_per_page, m.list_editable, m)
     300                m.list_select_related, m.list_per_page, m.list_max_show_all, m.list_editable, m)
    301301        self.assertEqual(cl.query_set.count(), 30)
    302302        self.assertEqual(cl.paginator.count, 30)
    303303        self.assertEqual(cl.paginator.page_range, [1, 2, 3])
     304   
     305    def test_show_all(self):
     306        parent = Parent.objects.create(name='anything')
     307        for i in range(30):
     308            Child.objects.create(name='name %s' % i, parent=parent)
     309            Child.objects.create(name='filtered %s' % i, parent=parent)
    304310
     311        request = MockRequest()
     312        # Add "show all" parameter to request
     313        request.GET[ALL_VAR] = []
     314       
     315        # Test valid "show all" request (number of total objects is under max)
     316        m = ChildAdmin(Child, admin.site)
     317        # 200 is the max we'll pass to ChangeList
     318        cl = ChangeList(request, Child, m.list_display, m.list_display_links,
     319                m.list_filter, m.date_hierarchy, m.search_fields,
     320                m.list_select_related, m.list_per_page, 200, m.list_editable, m)
     321        cl.get_results(request)
     322        self.assertEqual(len(cl.result_list), 60)
     323       
     324        # Test invalid "show all" request (number of total objects over max) raises exception
     325        m = ChildAdmin(Child, admin.site)
     326        # 30 is the max we'll pass to ChangeList for this test
     327        with self.assertRaises(IncorrectLookupParameters):
     328            cl = ChangeList(request, Child, m.list_display, m.list_display_links,
     329                    m.list_filter, m.date_hierarchy, m.search_fields,
     330                    m.list_select_related, m.list_per_page, 30, m.list_editable, m)
    305331
     332
    306333class ParentAdmin(admin.ModelAdmin):
    307334    list_filter = ['child__name']
    308335    search_fields = ['child__name']
  • tests/regressiontests/modeladmin/tests.py

     
    932932            list_per_page = 100
    933933
    934934        validate(ValidationTestModelAdmin, ValidationTestModel)
     935   
     936    def test_max_show_all_allowed_validation(self):
    935937
     938        class ValidationTestModelAdmin(ModelAdmin):
     939            list_max_show_all = 'hello'
     940
     941        self.assertRaisesRegexp(
     942            ImproperlyConfigured,
     943            "'ValidationTestModelAdmin.list_max_show_all' should be an integer.",
     944            validate,
     945            ValidationTestModelAdmin,
     946            ValidationTestModel,
     947        )
     948
     949        class ValidationTestModelAdmin(ModelAdmin):
     950            list_max_show_all = 200
     951
     952        validate(ValidationTestModelAdmin, ValidationTestModel)
     953
    936954    def test_search_fields_validation(self):
    937955
    938956        class ValidationTestModelAdmin(ModelAdmin):
Back to Top