Reporting issue with MultiWidget

30 views
Skip to first unread message

Anaël Megna

unread,
Apr 20, 2017, 12:38:09 PM4/20/17
to django...@googlegroups.com
Hello!

I think I have found out a issue in Django's source code.

I am trying to build a "Select or New" form field & widget, used by a ModelForm.
The goal of this field is the following:

- I have a model ProductType, "defined by" a label only;

- I have a model Product with a Foreign Key to this ProductType;

- I want to create a ProductForm(ModelForm) but with the possibility to create a ProductType at the same time.
(I could use a simple CharField with a get_or_create call, but this time, I wanted to learn to create Fields &
Widgets and propose to the user a Select with the different choices and a special choice "new type" that will read a
second text_input)

So I was planning to make this custom field using a MultiValueField with a ModelChoiceField and a CharField in it.
I constructed the ModelChoiceField with required=True and the CharField with required=False.

The widget attribute is the tuple of the ModelChoiceField.widget and the CharField.widget.

The problem (I think it is a problem, sorry if I'm just a noob) is that the context created by the MultiWidget is
bad-formed.
{'widget': {'required': True, <---- The ModelField found that on my Model
'subwidgets': [{'attrs': {'autofocus': 'autofocus',
'id': 'id_type_0',
'required': True}, <---- So it copied it there
'is_hidden': False,
'name': 'type_0',
'optgroups': [...],
'required': True, <---- This one correspond to my required=True
'template_name': 'django/forms/widgets/select.html',
'value': ['']},
{'attrs': {'autofocus': 'autofocus',
'id': 'id_type_1',
'required': True}, <---- And there
'is_hidden': False,
'name': 'type_1',
'required': False, <---- This one correspond to my required=False
'template_name': 'django/forms/widgets/text.html',
'type': 'text',
'value': None}],
'template_name': 'django/forms/widgets/multiwidget.html',
'value': None}}

So to quickly fix that, I wrote that in my MultiWidget.get_context() method:

for widget in context['widget']['subwidgets']:
widget['attrs']['required'] = widget['required']

I think it is provoked by the fact the only created BoundField is made on the MultiValueField, and ignores the inner
fields (and possible attrs created by them) and that the only way for MultiWidget to preserve its attrs (to pass them to
the HTML) is to overwrite those of its inner Widgets (done in the MultiWidget.get_context() method).

Sorry for my english. I hope this can help you! I really love Django!
Ask me if you have some questions or if there is something I have poorly explained.

Best regards,

Anaël
Reply all
Reply to author
Forward
0 new messages