BooleanField with choices in ModelForm does not show selected value in MySQL
|Reported by:||jittat <jittat@…>||Owned by:||nobody|
|Severity:||Keywords:||ModelForm, MySQL, BooleanField|
|Has patch:||no||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
From ticket #7190 BooleanField in MySQL would return 0 or 1. When it is used in ModelForm, this BooleanField will be rendered as TypedChoiceField using Select widget. A problem occurs when the field has choices.
How to reproduce:
- Create a model in MySQL with BooleanField with choices, e.g.,
class MyModel(models.Model): is_working = models.BooleanField( choices=((False,"This doesn't work"), (True,"This works!")))
- In ./manage.py shell, try the following:
>>> from testbf.models import MyModel >>> m = MyModel() >>> m.is_working = True >>> m.save() >>> m.is_working True >>> n = MyModel.objects.all() >>> n.is_working 1 >>> from django.forms import ModelForm >>> class MyModelForm(ModelForm): ... class Meta: ... model = MyModel ... >>> f = MyModelForm(instance=n) >>> f.as_p() u'<p><label for="id_is_working">Is working:</label> <select name="is_working" id="id_is_working">\n <option value="False">This doesn't work</option>\n <option value="True">This works!</option>\n </select></p>'
The correct output should have attribute selected="selected" in <option value="True">
The code for checking selected value is in forms.widgets.Select.render_options.render_option is
def render_option(option_value, option_label): option_value = force_unicode(option_value) selected_html = (option_value in selected_choices) and u' selected="selected"' or '' return u'<option value="%s"%s>%s</option>' % ( escape(option_value), selected_html, conditional_escape(force_unicode(option_label)))
Now, the option_value is converted to unicode, and True is converted to u'True'. However, the choices in selected_choices is [u'1'] (because the value returned by BooleanField in MySQL is 1).
Therefore, the expression: (option_value in selected_choices) is false, and the selected="selected" is not included in the rendered html.
I have no idea how to patch it. There are too many places to start, as the value is passed from models.BooleanField to forms.BoundField and to Select widget in TypedChoiceField.