I have a ModelForm
FormC
which inherits from FormA
and FormB
.
class FormA(forms.ModelForm):
class Meta:
widgets = {
'fieldA': forms.CheckboxSelectMultiple()
}
class FormB(forms.ModelForm):
class Meta:
widgets = {
'fieldB': forms.CheckboxSelectMultiple()
}
class FormC(formA, formB):
class Meta(FormA.Meta, FormB.Meta):
widgets = FormA.Meta.widgets | FormB.Meta.widgets
is this a good way to inherit widgets or is there a better way to do it?
Welcome @andreage !
Assumption: There is intended to be more in FormA
and FormB
than just the widgets
dict. (The assumption being that they’re otherwise complete model forms and you are just showing an extract.)
<opinion>
This would concern me.
Forms (like Models) are actually classes constructed from a metaclass. I’d be worried about what gets called during the class construction and whether or not what’s generated is “right”. I’d also be a little concerned about what’s going to be called in an overridden method when calling super()...
.
Personally, I wouldn’t do this. (But then we tend to mangle forms our own way.)
If I had to do this, I’d create an independent set of classes for just the widgets
dict as a Mixin and use them accordingly.
Do I know that something isn’t going to work? Nope. What I know is conjectural and theoretical. (I realize the parallel with Models isn’t perfect, but I have nothing better to go on.)
This may work perfectly well, I don’t know.
It just doesn’t “smell right” to me, but I have no evidence or proof that there’s anything wrong with it.
</opinion>
Yes, your assumption is right.
FormA
is related to the abstract ModelA
and FormB
to the abstract ModelB
. I then have the concrete ModelC(ModelA, ModelB)
. Therefore I wanted to keep the forms separated.
Also I might have for example ModelD(ModelA)
, therefore FormD(FormA)
.
Do you think the following is better or how would you approach it?
class FormA(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['formA'].widget = forms.CheckboxSelectMultiple()
class FormB(forms.ModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['formB'].widget = forms.CheckboxSelectMultiple()
class FormC(formA, formB):
pass
Again, this is all conjecture, opinions, and impressions on my part, and not from any direct knowledge.
However, I would never construct a form with:
class SomeForm(AForm, BForm):
where AForm
and BForm
are subclasses of Form
. Everything other than the base class would need to be something designed as a Mixin class and not be a full form instance.
So I would approach it as
class FormAMixin:
... stuff ...
class FormBMixin:
... stuff ...
class FormA(FormAMixin, ModelForm):
... stuff ...
class FormB(FormBMixin, ModelForm):
... stuff ...
class FormC(FormAMixin, FormBMixin, ModelForm):
... stuff ...
Oh, I see what you mean now, thank you.