Commit d5f89ff6 authored by Yoong Kang Lim's avatar Yoong Kang Lim Committed by Tim Graham
Browse files

Fixed #24974 -- Fixed inheritance of formfield_callback for modelform_factory forms.

parent 766afc22
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -209,7 +209,13 @@ class ModelFormOptions(object):

class ModelFormMetaclass(DeclarativeFieldsMetaclass):
    def __new__(mcs, name, bases, attrs):
        formfield_callback = attrs.pop('formfield_callback', None)
        base_formfield_callback = None
        for b in bases:
            if hasattr(b, 'Meta') and hasattr(b.Meta, 'formfield_callback'):
                base_formfield_callback = b.Meta.formfield_callback
                break

        formfield_callback = attrs.pop('formfield_callback', base_formfield_callback)

        new_class = super(ModelFormMetaclass, mcs).__new__(mcs, name, bases, attrs)

@@ -530,7 +536,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
    if hasattr(form, 'Meta'):
        parent = (form.Meta, object)
    Meta = type(str('Meta'), parent, attrs)

    if formfield_callback:
        Meta.formfield_callback = staticmethod(formfield_callback)
    # Give this new form class a reasonable name.
    class_name = model.__name__ + str('Form')

+22 −0
Original line number Diff line number Diff line
@@ -2736,6 +2736,28 @@ class FormFieldCallbackTests(SimpleTestCase):
        with self.assertRaises(TypeError):
            modelform_factory(Person, fields="__all__", formfield_callback='not a function or callable')

    def test_inherit_after_custom_callback(self):
        def callback(db_field, **kwargs):
            if isinstance(db_field, models.CharField):
                return forms.CharField(widget=forms.Textarea)
            return db_field.formfield(**kwargs)

        class BaseForm(forms.ModelForm):
            class Meta:
                model = Person
                fields = '__all__'

        NewForm = modelform_factory(Person, form=BaseForm, formfield_callback=callback)

        class InheritedForm(NewForm):
            pass

        for name in NewForm.base_fields.keys():
            self.assertEqual(
                type(InheritedForm.base_fields[name].widget),
                type(NewForm.base_fields[name].widget)
            )


class LocalizedModelFormTest(TestCase):
    def test_model_form_applies_localize_to_some_fields(self):