Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.4.x] Fixed #19318 -- Ensured that the admin's SimpleListFilter opt…

…ions can be displayed as selected even if the lookup's first element is not a string.

Backport of 88e1715
  • Loading branch information...
commit c72172244ef81f793d1eca9a54f58a11f27b0917 1 parent 3e4058b
Sebastián Magrí authored November 18, 2012 jphalip committed December 03, 2012
4  django/contrib/admin/filters.py
@@ -9,7 +9,7 @@
9 9
 
10 10
 from django.db import models
11 11
 from django.core.exceptions import ImproperlyConfigured, ValidationError
12  
-from django.utils.encoding import smart_unicode
  12
+from django.utils.encoding import smart_unicode, force_unicode
13 13
 from django.utils.translation import ugettext_lazy as _
14 14
 from django.utils import timezone
15 15
 from django.contrib.admin.util import (get_model_from_relation,
@@ -102,7 +102,7 @@ def choices(self, cl):
102 102
         }
103 103
         for lookup, title in self.lookup_choices:
104 104
             yield {
105  
-                'selected': self.value() == lookup,
  105
+                'selected': self.value() == force_unicode(lookup),
106 106
                 'query_string': cl.get_query_string({
107 107
                     self.parameter_name: lookup,
108 108
                 }, []),
58  tests/regressiontests/admin_filters/tests.py
@@ -77,6 +77,21 @@ class DecadeListFilterParameterEndsWith__Isnull(DecadeListFilter):
77 77
     parameter_name = 'decade__isnull' # Ends with '__isnull"
78 78
 
79 79
 
  80
+class DepartmentListFilterLookupWithNonStringValue(SimpleListFilter):
  81
+    title = 'department'
  82
+    parameter_name = 'department'
  83
+
  84
+    def lookups(self, request, model_admin):
  85
+        return set([
  86
+            (employee.department.id,  # Intentionally not a string (Refs #19318)
  87
+             employee.department.code)
  88
+            for employee in model_admin.queryset(request).all()
  89
+        ])
  90
+
  91
+    def queryset(self, request, queryset):
  92
+        if self.value():
  93
+            return queryset.filter(department__id=self.value())
  94
+
80 95
 class CustomUserAdmin(UserAdmin):
81 96
     list_filter = ('books_authored', 'books_contributed')
82 97
 
@@ -116,6 +131,8 @@ class EmployeeAdmin(ModelAdmin):
116 131
     list_display = ['name', 'department']
117 132
     list_filter = ['department']
118 133
 
  134
+class DepartmentFilterEmployeeAdmin(EmployeeAdmin):
  135
+    list_filter = [DepartmentListFilterLookupWithNonStringValue, ]
119 136
 
120 137
 class ListFiltersTests(TestCase):
121 138
 
@@ -139,6 +156,15 @@ def setUp(self):
139 156
         self.gipsy_book.contributors = [self.bob, self.lisa]
140 157
         self.gipsy_book.save()
141 158
 
  159
+        # Departments
  160
+        self.dev = Department.objects.create(code='DEV', description='Development')
  161
+        self.design = Department.objects.create(code='DSN', description='Design')
  162
+
  163
+        # Employees
  164
+        self.john = Employee.objects.create(name='John Blue', department=self.dev)
  165
+        self.jack = Employee.objects.create(name='Jack Red', department=self.design)
  166
+
  167
+
142 168
     def get_changelist(self, request, model, modeladmin):
143 169
         return ChangeList(request, model, modeladmin.list_display, modeladmin.list_display_links,
144 170
             modeladmin.list_filter, modeladmin.date_hierarchy, modeladmin.search_fields,
@@ -637,6 +663,29 @@ def test_parameter_ends_with__in__or__isnull(self):
637 663
         self.assertEqual(choices[2]['selected'], True)
638 664
         self.assertEqual(choices[2]['query_string'], '?decade__isnull=the+90s')
639 665
 
  666
+    def test_lookup_with_non_string_value(self):
  667
+        """
  668
+        Ensure choices are set the selected class when using
  669
+        non-string values for lookups in SimpleListFilters
  670
+        Refs #19318
  671
+        """
  672
+
  673
+        modeladmin = DepartmentFilterEmployeeAdmin(Employee, site)
  674
+        request = self.request_factory.get('/', {'department': '1'})
  675
+        changelist = self.get_changelist(request, Employee, modeladmin)
  676
+
  677
+        queryset = changelist.get_query_set(request)
  678
+
  679
+        self.assertEqual(list(queryset), [self.john])
  680
+
  681
+        filterspec = changelist.get_filters(request)[0][-1]
  682
+        self.assertEqual(force_unicode(filterspec.title), u'department')
  683
+        choices = list(filterspec.choices(changelist))
  684
+
  685
+        self.assertEqual(choices[2]['display'], u'DEV')
  686
+        self.assertEqual(choices[2]['selected'], True)
  687
+        self.assertEqual(choices[2]['query_string'], '?department=1')
  688
+
640 689
     def test_fk_with_to_field(self):
641 690
         """
642 691
         Ensure that a filter on a FK respects the FK's to_field attribute.
@@ -644,17 +693,12 @@ def test_fk_with_to_field(self):
644 693
         """
645 694
         modeladmin = EmployeeAdmin(Employee, site)
646 695
 
647  
-        dev = Department.objects.create(code='DEV', description='Development')
648  
-        design = Department.objects.create(code='DSN', description='Design')
649  
-        john = Employee.objects.create(name='John Blue', department=dev)
650  
-        jack = Employee.objects.create(name='Jack Red', department=design)
651  
-
652 696
         request = self.request_factory.get('/', {})
653 697
         changelist = self.get_changelist(request, Employee, modeladmin)
654 698
 
655 699
         # Make sure the correct queryset is returned
656 700
         queryset = changelist.get_query_set(request)
657  
-        self.assertEqual(list(queryset), [jack, john])
  701
+        self.assertEqual(list(queryset), [self.jack, self.john])
658 702
 
659 703
         filterspec = changelist.get_filters(request)[0][-1]
660 704
         self.assertEqual(force_unicode(filterspec.title), u'department')
@@ -679,7 +723,7 @@ def test_fk_with_to_field(self):
679 723
 
680 724
         # Make sure the correct queryset is returned
681 725
         queryset = changelist.get_query_set(request)
682  
-        self.assertEqual(list(queryset), [john])
  726
+        self.assertEqual(list(queryset), [self.john])
683 727
 
684 728
         filterspec = changelist.get_filters(request)[0][-1]
685 729
         self.assertEqual(force_unicode(filterspec.title), u'department')

0 notes on commit c721722

Please sign in to comment.
Something went wrong with that request. Please try again.