CheckboxInput.value_from_datadict with '0'
|Reported by:||Dan Fairs||Owned by:||nobody|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
CheckboxInput's value_from_datadict returns the literal value if the value's lowercased form is not in 'true' or 'false'. This looks like it's based on the idea that if any value is present in the data dictionary for a checkbox, then the value of the checkbox is True.
This is fine as far as it goes. However, a problem arises if the value being posted happens to be the string '0' (single character string, character is 0). This *should* be interpreted as a True value (ie. checkbox checked). When the string '0' is passed into BooleanField.to_python() (as would happen if a CheckboxInput is used on a ModelForm's BooleanField), False will be returned (presumably for RadioSelect compatibility). So, it is False that will be present in the cleaned_data dictionary that is used in form clean_* methods.
(Normally, a browser wouldn't provide '0' as a value, but badly-behaving clients may do - particularly if Django forms are used as part of data validation an API, which is where we discovered this problem.)
A fix for this is for CheckboxInput.value_from_datadict to always bool() its return value. This will result in True being returned for the case of '0' being in the data dictionary, which of course won't be special-cased in BooleanField.to_python.
I'll attach a patch and test shortly.