Fixed #9969: choices with options groups (added in [7977]) now work correctly in the admin with list_display and list_filter. Thanks, ramiro.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10318 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss 2009-04-01 14:14:20 +00:00
parent a2dec37c41
commit ee17cabba0
6 changed files with 64 additions and 4 deletions

View File

@ -90,7 +90,7 @@ class ChoicesFilterSpec(FilterSpec):
yield {'selected': self.lookup_val is None, yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': _('All')} 'display': _('All')}
for k, v in self.field.choices: for k, v in self.field.flatchoices:
yield {'selected': smart_unicode(k) == self.lookup_val, yield {'selected': smart_unicode(k) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: k}), 'query_string': cl.get_query_string({self.lookup_kwarg: k}),
'display': v} 'display': v}

View File

@ -205,8 +205,8 @@ def items_for_result(cl, result, form):
result_repr = EMPTY_CHANGELIST_VALUE result_repr = EMPTY_CHANGELIST_VALUE
# Fields with choices are special: Use the representation # Fields with choices are special: Use the representation
# of the choice. # of the choice.
elif f.choices: elif f.flatchoices:
result_repr = dict(f.choices).get(field_val, EMPTY_CHANGELIST_VALUE) result_repr = dict(f.flatchoices).get(field_val, EMPTY_CHANGELIST_VALUE)
else: else:
result_repr = escape(field_val) result_repr = escape(field_val)
if force_unicode(result_repr) == '': if force_unicode(result_repr) == '':

View File

@ -28,3 +28,4 @@ site = Admin2(name="admin2")
site.register(models.Article, models.ArticleAdmin) site.register(models.Article, models.ArticleAdmin)
site.register(models.Section, inlines=[models.ArticleInline]) site.register(models.Section, inlines=[models.ArticleInline])
site.register(models.Thing, models.ThingAdmin) site.register(models.Thing, models.ThingAdmin)
site.register(models.Fabric, models.FabricAdmin)

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<django-objects version="1.0">
<object pk="1" model="admin_views.fabric">
<field type="CharField" name="surface">x</field>
</object>
<object pk="2" model="admin_views.fabric">
<field type="CharField" name="surface">y</field>
</object>
<object pk="3" model="admin_views.fabric">
<field type="CharField" name="surface">plain</field>
</object>
</django-objects>

View File

@ -135,6 +135,21 @@ class Thing(models.Model):
class ThingAdmin(admin.ModelAdmin): class ThingAdmin(admin.ModelAdmin):
list_filter = ('color',) list_filter = ('color',)
class Fabric(models.Model):
NG_CHOICES = (
('Textured', (
('x', 'Horizontal'),
('y', 'Vertical'),
)
),
('plain', 'Smooth'),
)
surface = models.CharField(max_length=20, choices=NG_CHOICES)
class FabricAdmin(admin.ModelAdmin):
list_display = ('surface',)
list_filter = ('surface',)
class Person(models.Model): class Person(models.Model):
GENDER_CHOICES = ( GENDER_CHOICES = (
(1, "Male"), (1, "Male"),
@ -283,6 +298,7 @@ admin.site.register(ExternalSubscriber, ExternalSubscriberAdmin)
admin.site.register(Podcast, PodcastAdmin) admin.site.register(Podcast, PodcastAdmin)
admin.site.register(Parent, ParentAdmin) admin.site.register(Parent, ParentAdmin)
admin.site.register(EmptyModel, EmptyModelAdmin) admin.site.register(EmptyModel, EmptyModelAdmin)
admin.site.register(Fabric, FabricAdmin)
# We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2.
# That way we cover all four cases: # That way we cover all four cases:

View File

@ -21,7 +21,7 @@ except NameError:
from sets import Set as set from sets import Set as set
class AdminViewBasicTest(TestCase): class AdminViewBasicTest(TestCase):
fixtures = ['admin-views-users.xml', 'admin-views-colors.xml'] fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml']
# Store the bit of the URL where the admin is registered as a class # Store the bit of the URL where the admin is registered as a class
# variable. That way we can test a second AdminSite just by subclassing # variable. That way we can test a second AdminSite just by subclassing
@ -182,6 +182,37 @@ class AdminViewBasicTest(TestCase):
response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'})
self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit)
def testNamedGroupFieldChoicesChangeList(self):
"""
Ensures the admin changelist shows correct values in the relevant column
for rows corresponding to instances of a model in which a named group
has been used in the choices option of a field.
"""
response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit)
self.failUnlessEqual(response.status_code, 200)
self.failUnless(
'<a href="1/">Horizontal</a>' in response.content and
'<a href="2/">Vertical</a>' in response.content,
"Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group."
)
def testNamedGroupFieldChoicesFilter(self):
"""
Ensures the filter UI shows correctly when at least one named group has
been used in the choices option of a model field.
"""
response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit)
self.failUnlessEqual(response.status_code, 200)
self.failUnless(
'<div id="changelist-filter">' in response.content,
"Expected filter not found in changelist view."
)
self.failUnless(
'<a href="?surface__exact=x">Horizontal</a>' in response.content and
'<a href="?surface__exact=y">Vertical</a>' in response.content,
"Changelist filter isn't showing options contained inside a model field 'choices' option named group."
)
class CustomModelAdminTest(AdminViewBasicTest): class CustomModelAdminTest(AdminViewBasicTest):
urlbit = "admin2" urlbit = "admin2"