diff --git a/django/contrib/admin/filterspecs.py b/django/contrib/admin/filterspecs.py index d6a4a0bc48..97f4cb2056 100644 --- a/django/contrib/admin/filterspecs.py +++ b/django/contrib/admin/filterspecs.py @@ -60,7 +60,7 @@ class RelatedFilterSpec(FilterSpec): self.lookup_title = f.verbose_name self.lookup_kwarg = '%s__%s__exact' % (f.name, f.rel.to._meta.pk.name) self.lookup_val = request.GET.get(self.lookup_kwarg, None) - self.lookup_choices = f.rel.to._default_manager.all() + self.lookup_choices = f.get_choices(include_blank=False) def has_output(self): return len(self.lookup_choices) > 1 @@ -72,8 +72,7 @@ class RelatedFilterSpec(FilterSpec): yield {'selected': self.lookup_val is None, 'query_string': cl.get_query_string({}, [self.lookup_kwarg]), 'display': _('All')} - for val in self.lookup_choices: - pk_val = getattr(val, self.field.rel.to._meta.pk.attname) + for pk_val, val in self.lookup_choices: yield {'selected': self.lookup_val == smart_unicode(pk_val), 'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}), 'display': val} diff --git a/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml b/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml new file mode 100644 index 0000000000..e1213561b9 --- /dev/null +++ b/tests/regressiontests/admin_views/fixtures/admin-views-colors.xml @@ -0,0 +1,19 @@ + + + + Red + 1 + + + Orange + 1 + + + Blue + 0 + + + Green + 0 + + diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 52e75699ea..d381edadd0 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -74,7 +74,24 @@ class ModelWithStringPrimaryKey(models.Model): def __unicode__(self): return self.id +class Color(models.Model): + value = models.CharField(max_length=10) + warm = models.BooleanField() + def __unicode__(self): + return self.value + +class Thing(models.Model): + title = models.CharField(max_length=20) + color = models.ForeignKey(Color, limit_choices_to={'warm': True}) + def __unicode__(self): + return self.title + +class ThingAdmin(admin.ModelAdmin): + list_filter = ('color',) + 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) diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index f331c12591..bc9d1d49ae 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -12,7 +12,7 @@ from django.utils.html import escape from models import Article, CustomArticle, Section, ModelWithStringPrimaryKey class AdminViewBasicTest(TestCase): - fixtures = ['admin-views-users.xml'] + fixtures = ['admin-views-users.xml', 'admin-views-colors.xml'] def setUp(self): self.client.login(username='super', password='secret') @@ -147,6 +147,19 @@ class AdminViewBasicTest(TestCase): response.content.index('Middle content') < response.content.index('Newest content'), "Results of sorting on ModelAdmin method are out of order." ) + + def testLimitedFilter(self): + """Ensure admin changelist filters do not contain objects excluded via limit_choices_to.""" + response = self.client.get('/test_admin/admin/admin_views/thing/') + self.failUnlessEqual(response.status_code, 200) + self.failUnless( + '
' in response.content, + "Expected filter not found in changelist view." + ) + self.failIf( + 'Blue' in response.content, + "Changelist filter not correctly limited by limit_choices_to." + ) def get_perm(Model, perm): """Return the permission object, for the Model"""