#27369: Multiple form fields can share the same widget instance
---------------------------------+-----------------------------
Reporter: Michal Petrucha | Owner: Michal Petrucha
Type: Bug | Status: assigned
Component: Forms | Version: master
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Easy pickings: 0 | UI/UX: 0
---------------------------------+-----------------------------
Say we have a custom form field that defines a certain HTML class on its
widget:
{{{#!python
class CustomChoiceField(ChoiceField):
widget = Select(attrs={'class': 'my-custom-class'})
}}}
If this field type is used for multiple fields in the same form, they will
all share the same widget instance. This leads to conflicts when setting
the fields' choices; since they all use the same widget instance, all
fields will render the same choices from the widget even though the fields
themselves might have different choices. The following test case fails,
for example:
{{{#!python
class TestForm(Form):
field1 = CustomChoiceField(choices=[])
field2 = CustomChoiceField(choices=[])
f = TestForm()
f.fields['field1'].choices = [("1", "1")]
f.fields['field2'].choices = [("2", "2")]
assert f.fields['field1'].widget.choices == [("1", "1")]
assert f.fields['field2'].widget.choices == [("2", "2")]
}}}
I took a deep dive, and found out that since the field instances
themselves share the widget instance (as it's a class attribute that
doesn't need to get instantiated in each field instance), when fields are
getting deepcopied in `BaseForm.__init__`, their copies all share one new
copy of the widget instance.
This is quite easy to fix by deepcopying the widget in the case where it
was specified as an instance, rather than a widget class. Patch coming up
in a couple of minutes.
--
Ticket URL: <https://code.djangoproject.com/ticket/27369>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/051.9dd85576c2abbe3a3a5f1fb1c3301290%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.