From 68b540c97751f052a7622a7ab80a32a7d89d2aa2 Mon Sep 17 00:00:00 2001 From: Vajrasky Kok Date: Sat, 9 Nov 2013 12:17:23 +0800 Subject: [PATCH] Fixed #21361 -- allowed access self.value() from SimpleListFilter lookup Reviewed by Chris Medrela. --- django/contrib/admin/filters.py | 6 +++--- tests/admin_filters/tests.py | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index 4d970c2f8b..1f8cb5ed61 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -67,13 +67,13 @@ class SimpleListFilter(ListFilter): raise ImproperlyConfigured( "The list filter '%s' does not specify " "a 'parameter_name'." % self.__class__.__name__) + if self.parameter_name in params: + value = params.pop(self.parameter_name) + self.used_parameters[self.parameter_name] = value lookup_choices = self.lookups(request, model_admin) if lookup_choices is None: lookup_choices = () self.lookup_choices = list(lookup_choices) - if self.parameter_name in params: - value = params.pop(self.parameter_name) - self.used_parameters[self.parameter_name] = value def has_output(self): return len(self.lookup_choices) > 0 diff --git a/tests/admin_filters/tests.py b/tests/admin_filters/tests.py index 8f379245a6..42012d201e 100644 --- a/tests/admin_filters/tests.py +++ b/tests/admin_filters/tests.py @@ -106,6 +106,17 @@ class DepartmentListFilterLookupWithUnderscoredParameter(DepartmentListFilterLoo parameter_name = 'department__whatever' +class DepartmentListFilterLookupWithDynamicValue(DecadeListFilterWithTitleAndParameter): + + def lookups(self, request, model_admin): + if self.value() == 'the 80s': + return (('the 90s', "the 1990's"),) + elif self.value() == 'the 90s': + return (('the 80s', "the 1980's"),) + else: + return (('the 80s', "the 1980's"), ('the 90s', "the 1990's"),) + + class CustomUserAdmin(UserAdmin): list_filter = ('books_authored', 'books_contributed') @@ -169,6 +180,10 @@ class DepartmentFilterUnderscoredEmployeeAdmin(EmployeeAdmin): list_filter = [DepartmentListFilterLookupWithUnderscoredParameter, ] +class DepartmentFilterDynamicValueBookAdmin(EmployeeAdmin): + list_filter = [DepartmentListFilterLookupWithDynamicValue, ] + + class ListFiltersTests(TestCase): def setUp(self): @@ -816,3 +831,25 @@ class ListFiltersTests(TestCase): self.assertEqual(choices[2]['display'], 'Design') self.assertEqual(choices[2]['selected'], False) self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') + + def test_lookup_with_dynamic_value(self): + """ + Ensure SimpleListFilter can access self.value() inside the lookup. + """ + modeladmin = DepartmentFilterDynamicValueBookAdmin(Book, site) + + def _test_choices(request, expected_displays): + changelist = self.get_changelist(request, Book, modeladmin) + filterspec = changelist.get_filters(request)[0][0] + self.assertEqual(force_text(filterspec.title), 'publication decade') + choices = tuple(c['display'] for c in filterspec.choices(changelist)) + self.assertEqual(choices, expected_displays) + + _test_choices(self.request_factory.get('/', {}), + ("All", "the 1980's", "the 1990's")) + + _test_choices(self.request_factory.get('/', {'publication-decade': 'the 80s'}), + ("All", "the 1990's")) + + _test_choices(self.request_factory.get('/', {'publication-decade': 'the 90s'}), + ("All", "the 1980's"))