Dictionary passed to widget attr gets mutated

25 views
Skip to first unread message

Leon Sasson

unread,
Oct 28, 2014, 11:30:00 PM10/28/14
to django...@googlegroups.com
When a dictionary is passed to a Widget as the `attr` kwarg, to be used in filling HTML attributes, this dictionary is mutated, so cannot be reused. See below example to see a clear problem with this. Note how in the first form, when printer as_p(), the second field (session_end) gets an incorrect 'type' HTML attribute. This was tested in django 1.6

from django import forms

class FormWithBug(forms.Form):
    attrs = {'type':'time', 'required':'true'}
    session_start = forms.TimeField(widget=forms.TimeInput(attrs= attrs))
    session_end = forms.TimeField(widget=forms.TimeInput(attrs=attrs))

class FormWithoutBug(forms.Form):
    session_start = forms.TimeField(widget=forms.TimeInput(attrs= {'type':'time', 'required':'true'}))
    session_end = forms.TimeField(widget=forms.TimeInput(attrs={'type':'time', 'required':'true'}))

FormWithBug().as_p()
FormWithoutBug().as_p()

In [36]: FormWithBug().as_p()
Out[36]: u'<p><label for="id_session_start">Session start:</label> <input id="id_session_start" name="session_start" required="true" type="time" /></p>\n<p><label for="id_session_end">Session end:</label> <input id="id_session_end" name="session_end" required="true" type="text" /></p>'

In [37]: FormWithoutBug().as_p()
Out[37]: u'<p><label for="id_session_start">Session start:</label> <input id="id_session_start" name="session_start" required="true" type="time" /></p>\n<p><label for="id_session_end">Session end:</label> <input id="id_session_end" name="session_end" required="true" type="time" /></p>'

Collin Anderson

unread,
Oct 29, 2014, 2:34:23 PM10/29/14
to django...@googlegroups.com
Hello,

Interesting. Sounds like something that could be documented.

Collin

Collin Anderson

unread,
Oct 29, 2014, 2:35:41 PM10/29/14
to django...@googlegroups.com
You could do this:

class FormWithoutBug(forms.Form):
    attrs = {'type':'time', 'required':'true'}
    session_start = forms.TimeField(widget=forms.TimeInput(attrs=attrs.copy()))
    session_end = forms.TimeField(widget=forms.TimeInput(attrs=attrs.copy()))
Reply all
Reply to author
Forward
0 new messages