From a0c77ada990ca1e61b37d7ecdcf533e88c11a510 Mon Sep 17 00:00:00 2001 From: James Bennett Date: Wed, 10 Mar 2010 08:37:17 +0000 Subject: [PATCH] Ensure that NullBooleanField displays the appropriate icon for null values in admin changelists. Refs #13071. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12746 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/admin/util.py | 6 ++++-- tests/regressiontests/admin_util/tests.py | 6 +++++- tests/regressiontests/admin_views/models.py | 2 ++ tests/regressiontests/admin_views/tests.py | 9 +++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py index bf1ae2f132..fc940ad908 100644 --- a/django/contrib/admin/util.py +++ b/django/contrib/admin/util.py @@ -337,12 +337,14 @@ def display_for_field(value, field): if field.flatchoices: return dict(field.flatchoices).get(value, EMPTY_CHANGELIST_VALUE) + # NullBooleanField needs special-case null-handling, so it comes + # before the general null test. + elif isinstance(field, models.BooleanField) or isinstance(field, models.NullBooleanField): + return _boolean_icon(value) elif value is None: return EMPTY_CHANGELIST_VALUE elif isinstance(field, models.DateField) or isinstance(field, models.TimeField): return formats.localize(value) - elif isinstance(field, models.BooleanField) or isinstance(field, models.NullBooleanField): - return _boolean_icon(value) elif isinstance(field, models.DecimalField): return formats.number_format(value, field.decimal_places) elif isinstance(field, models.FloatField): diff --git a/tests/regressiontests/admin_util/tests.py b/tests/regressiontests/admin_util/tests.py index 43d7057783..f874b318f9 100644 --- a/tests/regressiontests/admin_util/tests.py +++ b/tests/regressiontests/admin_util/tests.py @@ -1,6 +1,7 @@ from datetime import datetime import unittest +from django.conf import settings from django.db import models from django.utils.formats import localize from django.test import TestCase @@ -131,8 +132,11 @@ class UtilTests(unittest.TestCase): display_value = display_for_field(None, models.TimeField()) self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) + # Regression test for #13071: NullBooleanField has special + # handling. display_value = display_for_field(None, models.NullBooleanField()) - self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) + expected = u'None' % settings.ADMIN_MEDIA_PREFIX + self.assertEqual(display_value, expected) display_value = display_for_field(None, models.DecimalField()) self.assertEqual(display_value, EMPTY_CHANGELIST_VALUE) diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index dfdb18f0be..b8b4e50ba2 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -464,11 +464,13 @@ class Post(models.Model): title = models.CharField(max_length=100) content = models.TextField() posted = models.DateField(default=datetime.date.today) + public = models.NullBooleanField() def awesomeness_level(self): return "Very awesome." class PostAdmin(admin.ModelAdmin): + list_display = ['title', 'public'] readonly_fields = ('posted', 'awesomeness_level', 'coolness', lambda obj: "foo") inlines = [ diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index b66d2956f9..655478a9ed 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -253,6 +253,15 @@ class AdminViewBasicTest(TestCase): "Changelist filter isn't showing options contained inside a model field 'choices' option named group." ) + def testChangeListNullBooleanDisplay(self): + Post.objects.create(public=None) + # This hard-codes the URl because it'll fail if it runs + # against the 'admin2' custom admin (which doesn't have the + # Post model). + response = self.client.get("/test_admin/admin/admin_views/post/") + self.failUnless('icon-unknown.gif' in response.content) + print "Passed" + class SaveAsTests(TestCase): fixtures = ['admin-views-users.xml','admin-views-person.xml']