diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py --- a/django/contrib/admin/filterspecs.py +++ b/django/contrib/admin/filterspecs.py @@ -89,7 +89,7 @@ yield {'selected': self.lookup_val is None, 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'display': _('All')} - for k, v in self.field.choices: + for k, v in self.field.flatchoices: yield {'selected': smart_unicode(k) == self.lookup_val, 'query_string': cl.get_query_string({self.lookup_kwarg: k}), 'display': v} diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -134,12 +134,27 @@ class ThingAdmin(admin.ModelAdmin): 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_filter = ('surface',) + admin.site.register(Article, ArticleAdmin) admin.site.register(CustomArticle, CustomArticleAdmin) admin.site.register(Section, inlines=[ArticleInline]) admin.site.register(ModelWithStringPrimaryKey) admin.site.register(Color) admin.site.register(Thing, ThingAdmin) +admin.site.register(Fabric, FabricAdmin) # We intentionally register Promo and ChapterXtra1 but not Chapter nor ChapterXtra2. # That way we cover all four cases: diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -160,7 +160,24 @@ 'Blue' in response.content, "Changelist filter not correctly limited by limit_choices_to." ) - + + 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/admin/admin_views/fabric/') + self.failUnlessEqual(response.status_code, 200) + self.failUnless( + '