Skip to content
Browse files

[1.5.x] Fixed #16820 -- Treated '0' value as True for checkbox inputs

Thanks Dan Fairs for the report and the initial patch.

Backport of be29329 from master.
  • Loading branch information...
1 parent 02b66f1 commit fbb664066f8970279af020cf163cb364156290c3 @claudep claudep committed
2 django/forms/
@@ -528,7 +528,7 @@ def value_from_datadict(self, data, files, name):
values = {'true': True, 'false': False}
if isinstance(value, six.string_types):
value = values.get(value.lower(), value)
- return value
+ return bool(value)
def _has_changed(self, initial, data):
# Sometimes data or initial could be None or '' which should be the
5 tests/regressiontests/forms/tests/
@@ -269,6 +269,11 @@ class SignupForm(Form):
f = SignupForm({'email': '', 'get_spam': 'false'}, auto_id=False)
self.assertHTMLEqual(str(f['get_spam']), '<input type="checkbox" name="get_spam" />')
+ # A value of '0' should be interpreted as a True value (#16820)
+ f = SignupForm({'email': '', 'get_spam': '0'})
+ self.assertTrue(f.is_valid())
+ self.assertTrue(f.cleaned_data.get('get_spam'))
def test_widget_output(self):
# Any Field can have a Widget class passed to its constructor:
class ContactForm(Form):
4 tests/regressiontests/forms/tests/
@@ -225,6 +225,10 @@ def test_checkboxinput(self):
# checkboxes).
self.assertFalse(w.value_from_datadict({}, {}, 'testing'))
+ value = w.value_from_datadict({'testing': '0'}, {}, 'testing')
+ self.assertIsInstance(value, bool)
+ self.assertTrue(value)
self.assertFalse(w._has_changed(None, None))
self.assertFalse(w._has_changed(None, ''))
self.assertFalse(w._has_changed('', None))

2 comments on commit fbb6640

Django member

This is backwards incompatible in that I have the following code for an API which relies on the checkbox input returning the actual submitted value:

class BooleanChoiceField(forms.BooleanField):

    def clean(self, value):
         if value in (False, 'False', 'false', '0'):
            value = False
        elif value in (True, 'True', 'true', '1'):
            value = True
            raise ValidationError("Invalid choice '%s' for boolean field." % value)
        return value

Now value_from_datadict returns True for something like 'bad input'

Do you think I should rewrite my code with a different widget or should we made a change to Django itself?

Django member

Hi Tim,
Basically, I think that a BooleanField should return a boolean value. If you have a different specific need, I'd suggest you just subclass the form field and redefine clean(). Post on the ticket if you'd like some larger audience.

Please sign in to comment.
Something went wrong with that request. Please try again.