Index: django/contrib/admin/util.py =================================================================== --- django/contrib/admin/util.py (revision 11479) +++ django/contrib/admin/util.py (working copy) @@ -85,12 +85,8 @@ nh = _nest_help # Bind to local variable for performance if current_depth > 16: return # Avoid recursing too deep. - opts_seen = [] for related in opts.get_all_related_objects(): has_admin = related.model in admin_site._registry - if related.opts in opts_seen: - continue - opts_seen.append(related.opts) rel_opts_name = related.get_accessor_name() if isinstance(related.field.rel, models.OneToOneRel): try: @@ -148,9 +144,6 @@ perms_needed.add(related.opts.verbose_name) for related in opts.get_all_related_many_to_many_objects(): has_admin = related.model in admin_site._registry - if related.opts in opts_seen: - continue - opts_seen.append(related.opts) rel_opts_name = related.get_accessor_name() has_related_objs = False Index: tests/regressiontests/admin_views/tests.py =================================================================== --- tests/regressiontests/admin_views/tests.py (revision 11479) +++ tests/regressiontests/admin_views/tests.py (working copy) @@ -18,7 +18,7 @@ ExternalSubscriber, FooAccount, Gallery, ModelWithStringPrimaryKey, \ Person, Persona, Picture, Podcast, Section, Subscriber, Vodcast, \ Language, Collector, Widget, Grommet, DooHickey, FancyDoodad, Whatsit, \ - Category + Category, Color, MulticoloredThing try: set @@ -323,6 +323,10 @@ delete_user.user_permissions.add(get_perm(Section, Section._meta.get_delete_permission())) + delete_user.user_permissions.add(get_perm(Color, + Color._meta.get_delete_permission())) + delete_user.user_permissions.add(get_perm(MulticoloredThing, + MulticoloredThing._meta.get_delete_permission())) # login POST dicts self.super_login = { @@ -584,6 +588,15 @@ self.failUnlessEqual(logged.object_id, u'1') self.client.get('/test_admin/admin/logout/') + def testDeleteViewWithMultipleForeignKeysToSameTable(self): + """Regression for #11821.""" + red = Color.objects.create(value='Red') + thing1 = MulticoloredThing.objects.create(title='Thing 1', background_color=red) + self.client.get('/test_admin/admin/') + self.client.post('/test_admin/admin/', self.deleteuser_login) + response = self.client.get('/test_admin/admin/admin_views/color/%d/delete/' % red.id) + self.assertContains(response, 'admin_views/multicoloredthing/%d/' % thing1.id) + class AdminViewStringPrimaryKeyTest(TestCase): fixtures = ['admin-views-users.xml', 'string-primary-key.xml'] @@ -1605,4 +1618,3 @@ "Check the never-cache status of the Javascript i18n view" response = self.client.get('/test_admin/jsi18n/') self.failUnlessEqual(get_max_age(response), None) - Index: tests/regressiontests/admin_views/models.py =================================================================== --- tests/regressiontests/admin_views/models.py (revision 11479) +++ tests/regressiontests/admin_views/models.py (working copy) @@ -138,6 +138,13 @@ class ThingAdmin(admin.ModelAdmin): list_filter = ('color',) +class MulticoloredThing(models.Model): + title = models.CharField(max_length=20) + foreground_color = models.ForeignKey(Color, related_name='thing_foreground', blank=True, null=True) + background_color = models.ForeignKey(Color, related_name='thing_background', blank=True, null=True) + def __unicode__(self): + return self.title + class Fabric(models.Model): NG_CHOICES = ( ('Textured', ( @@ -426,6 +433,7 @@ admin.site.register(ModelWithStringPrimaryKey) admin.site.register(Color) admin.site.register(Thing, ThingAdmin) +admin.site.register(MulticoloredThing) admin.site.register(Person, PersonAdmin) admin.site.register(Persona, PersonaAdmin) admin.site.register(Subscriber, SubscriberAdmin)