Fixed #25299 -- Fixed crash with ModelAdmin.list_display value that clashes with a model reverse accessor.
This commit is contained in:
parent
8e631a3175
commit
9607a04041
|
@ -304,9 +304,14 @@ def _get_non_gfk_field(opts, name):
|
||||||
"""
|
"""
|
||||||
For historical reasons, the admin app relies on GenericForeignKeys as being
|
For historical reasons, the admin app relies on GenericForeignKeys as being
|
||||||
"not found" by get_field(). This could likely be cleaned up.
|
"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)
|
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()
|
raise FieldDoesNotExist()
|
||||||
return field
|
return field
|
||||||
|
|
||||||
|
|
|
@ -13,5 +13,9 @@ Bugfixes
|
||||||
field that is both a foreign and primary key (:ticket:`24951`).
|
field that is both a foreign and primary key (:ticket:`24951`).
|
||||||
|
|
||||||
* Fixed a migrations crash with ``GenericForeignKey`` (:ticket:`25040`).
|
* Fixed a migrations crash with ``GenericForeignKey`` (:ticket:`25040`).
|
||||||
|
|
||||||
* Made ``translation.override()`` clear the overridden language when a
|
* Made ``translation.override()`` clear the overridden language when a
|
||||||
translation isn't initially active (:ticket:`25295`).
|
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`).
|
||||||
|
|
|
@ -169,7 +169,11 @@ class ThingAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
|
|
||||||
class InquisitionAdmin(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):
|
class SketchAdmin(admin.ModelAdmin):
|
||||||
|
|
|
@ -4882,6 +4882,16 @@ class RawIdFieldsTest(TestCase):
|
||||||
self.assertNotContains(response2, "Kilbraken")
|
self.assertNotContains(response2, "Kilbraken")
|
||||||
self.assertContains(response2, "Palin")
|
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'],
|
@override_settings(PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
|
||||||
ROOT_URLCONF="admin_views.urls")
|
ROOT_URLCONF="admin_views.urls")
|
||||||
|
|
Loading…
Reference in New Issue