diff --git a/django/contrib/admin/views/main.py b/django/contrib/admin/views/main.py index 5da031db9d..b428473cf6 100644 --- a/django/contrib/admin/views/main.py +++ b/django/contrib/admin/views/main.py @@ -174,14 +174,8 @@ class ChangeList(object): result_count = paginator.count # Get the total number of objects, with no admin filters applied. - # Perform a slight optimization: - # full_result_count is equal to paginator.count if no filters - # were applied if self.model_admin.show_full_result_count: - if self.get_filters_params() or self.params.get(SEARCH_VAR): - full_result_count = self.root_queryset.count() - else: - full_result_count = result_count + full_result_count = self.root_queryset.count() else: full_result_count = None can_show_all = result_count <= self.list_max_show_all diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index a34c268ace..51f571ad3f 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -43,6 +43,22 @@ class DecadeListFilter(SimpleListFilter): return queryset.filter(year__gte=2000, year__lte=2009) +class NotNinetiesListFilter(SimpleListFilter): + title = "Not nineties books" + parameter_name = "book_year" + + def lookups(self, request, model_admin): + return ( + ('the 90s', "the 1990's"), + ) + + def queryset(self, request, queryset): + if self.value() == 'the 90s': + return queryset.filter(year__gte=1990, year__lte=1999) + else: + return queryset.exclude(year__gte=1990, year__lte=1999) + + class DecadeListFilterWithTitleAndParameter(DecadeListFilter): title = 'publication decade' parameter_name = 'publication-decade' @@ -179,6 +195,10 @@ class DecadeFilterBookAdmin(ModelAdmin): ordering = ('-id',) +class NotNinetiesListFilterAdmin(ModelAdmin): + list_filter = (NotNinetiesListFilter,) + + class DecadeFilterBookAdminWithoutTitle(ModelAdmin): list_filter = (DecadeListFilterWithoutTitle,) @@ -1026,3 +1046,14 @@ class ListFiltersTests(TestCase): _test_choices(self.request_factory.get('/', {'publication-decade': 'the 90s'}), ("All", "the 1980's")) + + def test_list_filter_queryset_filtered_by_default(self): + """ + A list filter that filters the queryset by default gives the correct + full_result_count. + """ + modeladmin = NotNinetiesListFilterAdmin(Book, site) + request = self.request_factory.get('/', {}) + changelist = self.get_changelist(request, Book, modeladmin) + changelist.get_results(request) + self.assertEqual(changelist.full_result_count, 4) diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index b6db228809..ba81860db6 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -3756,13 +3756,12 @@ class AdminCustomQuerysetTest(TestCase): Person.objects.create(name='person2', gender=2) changelist_url = reverse('admin:admin_views_person_changelist') - # 4 queries are expected: 1 for the session, 1 for the user, - # 1 for the count and 1 for the objects on the page - with self.assertNumQueries(4): + # 5 queries are expected: 1 for the session, 1 for the user, + # 2 for the counts and 1 for the objects on the page + with self.assertNumQueries(5): resp = self.client.get(changelist_url) self.assertEqual(resp.context['selection_note'], '0 of 2 selected') self.assertEqual(resp.context['selection_note_all'], 'All 2 selected') - # here one more count(*) query will run, because filters were applied with self.assertNumQueries(5): extra = {'q': 'not_in_name'} resp = self.client.get(changelist_url, extra)