Fixed #29322 -- Made admin check all ModelAdmin fieldsets for duplicates.

This commit is contained in:
Matthias Kestenholz 2018-04-13 17:08:30 +02:00 committed by Tim Graham
parent 0b66c3b442
commit 13efbb233a
2 changed files with 18 additions and 4 deletions

View File

@ -209,12 +209,13 @@ class BaseModelAdminChecks:
elif not isinstance(obj.fieldsets, (list, tuple)): elif not isinstance(obj.fieldsets, (list, tuple)):
return must_be('a list or tuple', option='fieldsets', obj=obj, id='admin.E007') return must_be('a list or tuple', option='fieldsets', obj=obj, id='admin.E007')
else: else:
seen_fields = []
return list(chain.from_iterable( return list(chain.from_iterable(
self._check_fieldsets_item(obj, obj.model, fieldset, 'fieldsets[%d]' % index) self._check_fieldsets_item(obj, obj.model, fieldset, 'fieldsets[%d]' % index, seen_fields)
for index, fieldset in enumerate(obj.fieldsets) for index, fieldset in enumerate(obj.fieldsets)
)) ))
def _check_fieldsets_item(self, obj, model, fieldset, label): def _check_fieldsets_item(self, obj, model, fieldset, label, seen_fields):
""" Check an item of `fieldsets`, i.e. check that this is a pair of a """ Check an item of `fieldsets`, i.e. check that this is a pair of a
set name and a dictionary containing "fields" key. """ set name and a dictionary containing "fields" key. """
@ -235,8 +236,8 @@ class BaseModelAdminChecks:
elif not isinstance(fieldset[1]['fields'], (list, tuple)): elif not isinstance(fieldset[1]['fields'], (list, tuple)):
return must_be('a list or tuple', option="%s[1]['fields']" % label, obj=obj, id='admin.E008') return must_be('a list or tuple', option="%s[1]['fields']" % label, obj=obj, id='admin.E008')
fields = flatten(fieldset[1]['fields']) seen_fields.extend(flatten(fieldset[1]['fields']))
if len(fields) != len(set(fields)): if len(seen_fields) != len(set(seen_fields)):
return [ return [
checks.Error( checks.Error(
"There are duplicate field(s) in '%s[1]'." % label, "There are duplicate field(s) in '%s[1]'." % label,

View File

@ -166,6 +166,19 @@ class FieldsetsCheckTests(CheckTestCase):
'admin.E012' 'admin.E012'
) )
def test_duplicate_fields_in_fieldsets(self):
class TestModelAdmin(ModelAdmin):
fieldsets = [
(None, {'fields': ['name']}),
(None, {'fields': ['name']}),
]
self.assertIsInvalid(
TestModelAdmin, ValidationTestModel,
"There are duplicate field(s) in 'fieldsets[1][1]'.",
'admin.E012'
)
def test_fieldsets_with_custom_form_validation(self): def test_fieldsets_with_custom_form_validation(self):
class BandAdmin(ModelAdmin): class BandAdmin(ModelAdmin):
fieldsets = (('Band', {'fields': ('name',)}),) fieldsets = (('Band', {'fields': ('name',)}),)