From e24c0a2d7cab08c2fdcd3f873a3e85f70cd718b4 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Sun, 11 Sep 2016 08:19:56 -0700 Subject: [PATCH] Fixed #26524 -- Fixed crash in admin change view when displaying many to many forward refs. Thanks Tim Graham for the regression test. --- django/contrib/admin/utils.py | 2 +- tests/admin_views/models.py | 4 ++++ tests/admin_views/tests.py | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 9b312ac30e..eb64391647 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -317,7 +317,7 @@ def _get_non_gfk_field(opts, name): raise FieldDoesNotExist() # Avoid coercing _id fields to FK - if field.is_relation and hasattr(field, 'attname') and field.attname == name: + if field.is_relation and not field.many_to_many and hasattr(field, 'attname') and field.attname == name: raise FieldIsAForeignKeyColumnName() return field diff --git a/tests/admin_views/models.py b/tests/admin_views/models.py index 8828c8b4da..4d500cd9e6 100644 --- a/tests/admin_views/models.py +++ b/tests/admin_views/models.py @@ -596,9 +596,13 @@ class CyclicTwo(models.Model): return self.name +@python_2_unicode_compatible class Topping(models.Model): name = models.CharField(max_length=20) + def __str__(self): + return self.name + class Pizza(models.Model): name = models.CharField(max_length=20) diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 3368ddf3d6..ccc38920d0 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -4696,6 +4696,14 @@ class ReadonlyTest(AdminFieldExtractionMixin, TestCase): response = self.client.get(reverse('admin:admin_views_topping_add')) self.assertEqual(response.status_code, 200) + def test_readonly_manytomany_forwards_ref(self): + topping = Topping.objects.create(name='Salami') + pizza = Pizza.objects.create(name='Americano') + pizza.toppings.add(topping) + response = self.client.get(reverse('admin:admin_views_pizza_change', args=(pizza.pk,))) + self.assertContains(response, '', html=True) + self.assertContains(response, '

Salami

', html=True) + def test_readonly_onetoone_backwards_ref(self): """ Can reference a reverse OneToOneField in ModelAdmin.readonly_fields.