diff --git a/django/contrib/admin/checks.py b/django/contrib/admin/checks.py index 4bf548223d..47e40d62ab 100644 --- a/django/contrib/admin/checks.py +++ b/django/contrib/admin/checks.py @@ -806,10 +806,10 @@ class ModelAdminChecks(BaseModelAdminChecks): id='admin.E123', ) ] - # Check that list_display_links is set, and that the first values of list_editable and list_display are - # not the same. See ticket #22792 for the use case relating to this. - elif (obj.list_display[0] in obj.list_editable and obj.list_display[0] != obj.list_editable[0] and - obj.list_display_links is not None): + # If list_display[0] is in list_editable, check that + # list_display_links is set. See #22792 and #26229 for use cases. + elif (obj.list_display[0] == field_name and not obj.list_display_links + and obj.list_display_links is not None): return [ checks.Error( "The value of '%s' refers to the first field in 'list_display' ('%s'), " diff --git a/tests/modeladmin/tests.py b/tests/modeladmin/tests.py index 3e2dfe261b..c7e4b2c29d 100644 --- a/tests/modeladmin/tests.py +++ b/tests/modeladmin/tests.py @@ -1553,10 +1553,10 @@ class ListDisplayEditableTests(CheckTestCase): list_display_links = None self.assertIsValid(ProductAdmin, ValidationTestModel) - def test_list_display_same_as_list_editable(self): + def test_list_display_first_item_same_as_list_editable_first_item(self): """ - The first item in list_display can be the same as the first - in list_editable + The first item in list_display can be the same as the first in + list_editable. """ class ProductAdmin(ModelAdmin): list_display = ['name', 'slug', 'pub_date'] @@ -1564,6 +1564,49 @@ class ListDisplayEditableTests(CheckTestCase): list_display_links = ['pub_date'] self.assertIsValid(ProductAdmin, ValidationTestModel) + def test_list_display_first_item_in_list_editable(self): + """ + The first item in list_display can be in list_editable as long as + list_display_links is defined. + """ + class ProductAdmin(ModelAdmin): + list_display = ['name', 'slug', 'pub_date'] + list_editable = ['slug', 'name'] + list_display_links = ['pub_date'] + self.assertIsValid(ProductAdmin, ValidationTestModel) + + def test_list_display_first_item_same_as_list_editable_no_list_display_links(self): + """ + The first item in list_display cannot be the same as the first item + in list_editable if list_display_links is not defined. + """ + class ProductAdmin(ModelAdmin): + list_display = ['name'] + list_editable = ['name'] + self.assertIsInvalid( + ProductAdmin, ValidationTestModel, + "The value of 'list_editable[0]' refers to the first field " + "in 'list_display' ('name'), which cannot be used unless " + "'list_display_links' is set.", + id='admin.E124', + ) + + def test_list_display_first_item_in_list_editable_no_list_display_links(self): + """ + The first item in list_display cannot be in list_editable if + list_display_links isn't defined. + """ + class ProductAdmin(ModelAdmin): + list_display = ['name', 'slug', 'pub_date'] + list_editable = ['slug', 'name'] + self.assertIsInvalid( + ProductAdmin, ValidationTestModel, + "The value of 'list_editable[1]' refers to the first field " + "in 'list_display' ('name'), which cannot be used unless " + "'list_display_links' is set.", + id='admin.E124', + ) + class ModelAdminPermissionTests(SimpleTestCase):