Fixed #18729 -- Made admin changelist not use distinct() if a list_filter doesn't require it.

This commit is contained in:
nmhung89 2016-10-23 21:55:53 +10:00 committed by Tim Graham
parent d0112cf930
commit 8f76673f34
2 changed files with 23 additions and 2 deletions

View File

@ -125,11 +125,16 @@ class ChangeList(object):
if not isinstance(field, models.Field): if not isinstance(field, models.Field):
field_path = field field_path = field
field = get_fields_from_path(self.model, field_path)[-1] field = get_fields_from_path(self.model, field_path)[-1]
lookup_params_count = len(lookup_params)
spec = field_list_filter_class( spec = field_list_filter_class(
field, request, lookup_params, field, request, lookup_params,
self.model, self.model_admin, field_path=field_path self.model, self.model_admin, field_path=field_path
) )
# Check if we need to use distinct() # field_list_filter_class removes any lookup_params it
# processes. If that happened, check if distinct() is
# needed to remove duplicate results.
if lookup_params_count > len(lookup_params):
use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path) use_distinct = use_distinct or lookup_needs_distinct(self.lookup_opts, field_path)
if spec and spec.has_output(): if spec and spec.has_output():
filter_specs.append(spec) filter_specs.append(spec)

View File

@ -445,6 +445,22 @@ class ChangeListTests(TestCase):
# There's only one Concert instance # There's only one Concert instance
self.assertEqual(cl.queryset.count(), 1) self.assertEqual(cl.queryset.count(), 1)
def test_no_distinct_for_m2m_in_list_filter_without_params(self):
"""
If a ManyToManyField is in list_filter but isn't in any lookup params,
the changelist's query shouldn't have distinct.
"""
m = BandAdmin(Band, custom_site)
for lookup_params in ({}, {'name': 'test'}):
request = self.factory.get('/band/', lookup_params)
cl = ChangeList(request, Band, *get_changelist_args(m))
self.assertFalse(cl.queryset.query.distinct)
# A ManyToManyField in params does have distinct applied.
request = self.factory.get('/band/', {'genres': '0'})
cl = ChangeList(request, Band, *get_changelist_args(m))
self.assertTrue(cl.queryset.query.distinct)
def test_pagination(self): def test_pagination(self):
""" """
Regression tests for #12893: Pagination in admins changelist doesn't Regression tests for #12893: Pagination in admins changelist doesn't