summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2015-08-24 11:52:58 -0400
committerTim Graham <timograham@gmail.com>2015-08-28 09:03:34 -0400
commit3cc67a637a3cd1426d2ac87d7418600fa247ebb2 (patch)
treef28b96aee6830482ee067f58f85b8212577a69b9
parent4f83bfa9e5ef10c6c9711ad529630d09a06ef413 (diff)
[1.8.x] Fixed #25299 -- Fixed crash with ModelAdmin.list_display value that clashes with a model reverse accessor.
Backport of 9607a0404188bbe612f05216f5a82df26f4b4e80 from master
-rw-r--r--django/contrib/admin/utils.py7
-rw-r--r--docs/releases/1.8.5.txt4
-rw-r--r--tests/admin_views/admin.py6
-rw-r--r--tests/admin_views/tests.py10
4 files changed, 25 insertions, 2 deletions
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index 619e9ad796..8ddba506b0 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -293,9 +293,14 @@ def _get_non_gfk_field(opts, name):
"""
For historical reasons, the admin app relies on GenericForeignKeys as being
"not found" by get_field(). This could likely be cleaned up.
+
+ Reverse relations should also be excluded as these aren't attributes of the
+ model (rather something like `foo_set`).
"""
field = opts.get_field(name)
- if field.is_relation and field.many_to_one and not field.related_model:
+ if (field.is_relation and
+ # Generic foreign keys OR reverse relations
+ ((field.many_to_one and not field.related_model) or field.one_to_many)):
raise FieldDoesNotExist()
return field
diff --git a/docs/releases/1.8.5.txt b/docs/releases/1.8.5.txt
index 3f1674b979..543e8824be 100644
--- a/docs/releases/1.8.5.txt
+++ b/docs/releases/1.8.5.txt
@@ -13,5 +13,9 @@ Bugfixes
field that is both a foreign and primary key (:ticket:`24951`).
* Fixed a migrations crash with ``GenericForeignKey`` (:ticket:`25040`).
+
* Made ``translation.override()`` clear the overridden language when a
translation isn't initially active (:ticket:`25295`).
+
+* Fixed crash when using a value in ``ModelAdmin.list_display`` that clashed
+ with a reverse field on the model (:ticket:`25299`).
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py
index 158f42ea67..b4e67f0a23 100644
--- a/tests/admin_views/admin.py
+++ b/tests/admin_views/admin.py
@@ -169,7 +169,11 @@ class ThingAdmin(admin.ModelAdmin):
class InquisitionAdmin(admin.ModelAdmin):
- list_display = ('leader', 'country', 'expected')
+ list_display = ('leader', 'country', 'expected', 'sketch')
+
+ def sketch(self, obj):
+ # A method with the same name as a reverse accessor.
+ return 'list-display-sketch'
class SketchAdmin(admin.ModelAdmin):
diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py
index b5dff27e6b..dd96715605 100644
--- a/tests/admin_views/tests.py
+++ b/tests/admin_views/tests.py
@@ -4230,6 +4230,16 @@ class RawIdFieldsTest(TestCase):
self.assertNotContains(response2, "Kilbraken")
self.assertContains(response2, "Palin")
+ def test_list_display_method_same_name_as_reverse_accessor(self):
+ """
+ Should be able to use a ModelAdmin method in list_display that has the
+ same name as a reverse model field ("sketch" in this case).
+ """
+ actor = Actor.objects.create(name="Palin", age=27)
+ Inquisition.objects.create(expected=True, leader=actor, country="England")
+ response = self.client.get(reverse('admin:admin_views_inquisition_changelist'))
+ self.assertContains(response, 'list-display-sketch')
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',),
ROOT_URLCONF="admin_views.urls")