I have two forms
class FirstForm(forms.Form):
pick = forms.ChoiceField(
widget=forms.Select(attrs={"onchange": "this.form.submit();"})
)
class SecondForm(forms.ModelForm):
class Meta:
fields = "__all__"
widgets = {
"pick": forms.Select(attrs={"onchange": "this.form.submit();"}),
}
While FirstForm
derives from forms.Form
, and SecondForm
derives from forms.ModelForm
“pick” in both forms should trigger a submission when selection changes.
Observation:
FirstForm
produces the desired results (the form submits when selection changes).
SecondForm
does nothing. The form does not submit when selection changes.
Question:
Why is SecondForm
failing? Are widgets made from Models different from those in ordinary Forms?
I would look at the rendered html in the browser in both cases to see what the differences might be between the widgets being rendered.
The behavior you’re observing with FirstForm
and SecondForm
is related to the difference in how widgets are rendered and processed in a regular form (FirstForm
) and a model form (SecondForm
). The issue is not related to whether the form is derived from forms.Form
or forms.ModelForm
. Instead, it’s caused by the way the form fields and widgets are defined.
In FirstForm
, you’re correctly using the widget
attribute for the pick
field to add an onchange
attribute to the Select
input field. This attribute triggers form submission when the selection changes, and it works as expected.
In SecondForm
, you’re using the widgets
attribute inside the Meta
class to define the widget for the pick
field. However, the widgets
attribute is used to specify the default widgets for model form fields, and in this case, it doesn’t add the onchange
attribute to the Select
input field.
To make it work in SecondForm
, you should set the widget
attribute directly on the field definition in the form class, just like you did in FirstForm
. Here’s how you can modify SecondForm
to achieve the desired behavior:
class SecondForm(forms.ModelForm):
pick = forms.ChoiceField(
widget=forms.Select(attrs={"onchange": "this.form.submit();"})
)
class Meta:
model = YourModelName # Replace with your actual model
fields = "__all__"
By setting the widget
attribute for the pick
field directly in the form class, you’ll ensure that the onchange
attribute is added to the Select
input field, and the form will submit when the selection changes. This should make SecondForm
work as expected.
I have found the issue.
The fault is not from forms.ModelForm
. Those forms were perfect. The issue was with the template. In the template, I had a button within the <form></form>
tags that was named “submit”. That button was conflicting with the js method “this.form.submit()
”