Commit 9d1987d7 authored by Lukasz Balcerzak's avatar Lukasz Balcerzak Committed by Tim Graham
Browse files

Fixed #19303 -- Fixed ModelAdmin.formfield_overrides on fields with choices

parent 65cf82bd
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
        validator.validate(cls, model)

    def __init__(self):
        self._orig_formfield_overrides = self.formfield_overrides
        overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy()
        overrides.update(self.formfield_overrides)
        self.formfield_overrides = overrides
@@ -123,6 +124,9 @@ class BaseModelAdmin(six.with_metaclass(RenameBaseModelAdminMethods)):
        # If the field specifies choices, we don't need to look for special
        # admin widgets - we just need to use a select widget of some kind.
        if db_field.choices:
            # see #19303 for an explanation of self._orig_formfield_overrides
            if db_field.__class__ in self._orig_formfield_overrides:
                kwargs = dict(self._orig_formfield_overrides[db_field.__class__], **kwargs)
            return self.formfield_for_choice_field(db_field, request, **kwargs)

        # ForeignKey or ManyToManyFields
+17 −0
Original line number Diff line number Diff line
@@ -132,6 +132,23 @@ class AdminFormfieldForDBFieldTests(TestCase):
        self.assertEqual(f2.widget.attrs['maxlength'], '20')
        self.assertEqual(f2.widget.attrs['size'], '10')

    def testFormfieldOverridesWidgetInstancesForFieldsWithChoices(self):
        """
        Test that widget is actually overridden for fields with choices.
        (#194303)
        """
        class MemberAdmin(admin.ModelAdmin):
            formfield_overrides = {
                CharField: {'widget': forms.TextInput}
            }
        ma = MemberAdmin(models.Member, admin.site)
        name_field = models.Member._meta.get_field('name')
        gender_field = models.Member._meta.get_field('gender')
        name = ma.formfield_for_dbfield(name_field, request=None)
        gender = ma.formfield_for_dbfield(gender_field, request=None)
        self.assertIsInstance(name.widget, forms.TextInput)
        self.assertIsInstance(gender.widget, forms.TextInput)

    def testFieldWithChoices(self):
        self.assertFormfield(models.Member, 'gender', forms.Select)