Browse Source

Fixed #16080 -- Handle admin list filter items with two characters better. Thanks, Ales Zoulek and Julien Phalip.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16274 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Jannis Leidel 14 years ago
parent
commit
4a4b6b271e

+ 5 - 7
django/contrib/admin/validation.py

@@ -73,18 +73,16 @@ def validate(cls, model):
                             " associated with a field name."
                             % (cls.__name__, idx, item.__name__))
             else:
-                try:
-                    # Check for option #2 (tuple)
-                    field, list_filter_class = item
-                except (TypeError, ValueError):
-                    # item is option #1
-                    field = item
-                else:
+                if isinstance(item, (tuple, list)):
                     # item is option #2
+                    field, list_filter_class = item
                     if not issubclass(list_filter_class, FieldListFilter):
                         raise ImproperlyConfigured("'%s.list_filter[%d][1]'"
                             " is '%s' which is not of type FieldListFilter."
                             % (cls.__name__, idx, list_filter_class.__name__))
+                else:
+                    # item is option #1
+                    field = item
                 # Validate the field string
                 try:
                     get_fields_from_path(model, field)

+ 3 - 3
django/contrib/admin/views/main.py

@@ -97,10 +97,10 @@ class ChangeList(object):
                         self.model, self.model_admin)
                 else:
                     field_path = None
-                    try:
-                        # This is custom FieldListFilter class for a given field.
+                    if isinstance(list_filer, (tuple, list)):
+                        # This is a custom FieldListFilter class for a given field.
                         field, field_list_filter_class = list_filer
-                    except (TypeError, ValueError):
+                    else:
                         # This is simply a field name, so use the default
                         # FieldListFilter class that has been registered for
                         # the type of the given field.

+ 1 - 0
tests/regressiontests/admin_filters/models.py

@@ -8,6 +8,7 @@ class Book(models.Model):
     contributors = models.ManyToManyField(User, related_name='books_contributed', blank=True, null=True)
     is_best_seller = models.NullBooleanField(default=0)
     date_registered = models.DateField(null=True)
+    no = models.IntegerField(verbose_name=u'number', blank=True, null=True) # This field is intentionally 2 characters long. See #16080.
 
     def __unicode__(self):
         return self.title

+ 22 - 3
tests/regressiontests/admin_filters/tests.py

@@ -66,7 +66,7 @@ class CustomUserAdmin(UserAdmin):
     list_filter = ('books_authored', 'books_contributed')
 
 class BookAdmin(ModelAdmin):
-    list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered')
+    list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no')
     order_by = '-id'
 
 class DecadeFilterBookAdmin(ModelAdmin):
@@ -100,8 +100,8 @@ class ListFiltersTests(TestCase):
 
         # Books
         self.djangonaut_book = Book.objects.create(title='Djangonaut: an art of living', year=2009, author=self.alfred, is_best_seller=True, date_registered=self.today)
-        self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False)
-        self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today)
+        self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False, no=207)
+        self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today, no=103)
         self.gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002, is_best_seller=True, date_registered=self.one_week_ago)
         self.gipsy_book.contributors = [self.bob, self.lisa]
         self.gipsy_book.save()
@@ -528,3 +528,22 @@ class ListFiltersTests(TestCase):
         self.assertEqual(choices[2]['display'], u'the 2000\'s')
         self.assertEqual(choices[2]['selected'], False)
         self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s')
+
+    def test_two_characters_long_field(self):
+        """
+        Ensure that list_filter works with two-characters long field names.
+        Refs #16080.
+        """
+        modeladmin = BookAdmin(Book, site)
+        request = self.request_factory.get('/', {'no': '207'})
+        changelist = self.get_changelist(request, Book, modeladmin)
+
+        # Make sure the correct queryset is returned
+        queryset = changelist.get_query_set(request)
+        self.assertEqual(list(queryset), [self.bio_book])
+
+        filterspec = changelist.get_filters(request)[0][-1]
+        self.assertEqual(force_unicode(filterspec.title), u'number')
+        choices = list(filterspec.choices(changelist))
+        self.assertEqual(choices[2]['selected'], True)
+        self.assertEqual(choices[2]['query_string'], '?no=207')

+ 1 - 0
tests/regressiontests/modeladmin/models.py

@@ -34,6 +34,7 @@ class ValidationTestModel(models.Model):
     is_active = models.BooleanField()
     pub_date = models.DateTimeField()
     band = models.ForeignKey(Band)
+    no = models.IntegerField(verbose_name="Number", blank=True, null=True) # This field is intentionally 2 characters long. See #16080.
 
     def decade_published_in(self):
         return self.pub_date.strftime('%Y')[:3] + "0's"

+ 1 - 1
tests/regressiontests/modeladmin/tests.py

@@ -911,7 +911,7 @@ class ValidationTests(unittest.TestCase):
         # Valid declarations below -----------
 
         class ValidationTestModelAdmin(ModelAdmin):
-            list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter))
+            list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter), 'no')
 
         validate(ValidationTestModelAdmin, ValidationTestModel)