diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index 9b95c31..4b629d2 100644
--- a/django/forms/widgets.py
+++ b/django/forms/widgets.py
@@ -491,7 +491,7 @@ class CheckboxInput(Widget):
         values =  {'true': True, 'false': False}
         if isinstance(value, basestring):
             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 u'' which should be the
diff --git a/tests/regressiontests/forms/tests/forms.py b/tests/regressiontests/forms/tests/forms.py
index ed783af..887d46e 100644
--- a/tests/regressiontests/forms/tests/forms.py
+++ b/tests/regressiontests/forms/tests/forms.py
@@ -1739,3 +1739,23 @@ class FormsTestCase(TestCase):
 
         form = EventForm()
         self.assertEqual(form.as_ul(), u'<input type="hidden" name="happened_at_0" id="id_happened_at_0" /><input type="hidden" name="happened_at_1" id="id_happened_at_1" />')
+
+    def test_checkbox_zero(self):
+        """ Integration test to demonstrate that '0' is treated as a True
+        value when fed through a checkbox input.
+        """
+        class FormWithCheckbox(forms.Form):
+            flag = BooleanField(widget=CheckboxInput, required=False)
+
+            def clean(self):
+                cleaned_data = super(FormWithCheckbox, self).clean()
+                if cleaned_data.get('flag'):
+                    raise forms.ValidationError, u'Flag must be false!'
+                return cleaned_data
+
+        form = FormWithCheckbox({'flag': '0'})
+
+        # The clean method raises a ValidationError if the flag field
+        # is True. Since '0' is actually provided, we expect this validation
+        # error to be raised, and the form to therefore be not valid.
+        self.assertFalse(form.is_valid())
diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
index b4ceb2f..79f8f8a 100644
--- a/tests/regressiontests/forms/tests/widgets.py
+++ b/tests/regressiontests/forms/tests/widgets.py
@@ -232,6 +232,16 @@ class FormsWidgetTestCase(TestCase):
         self.assertFalse(w._has_changed(True, u'on'))
         self.assertTrue(w._has_changed(True, u''))
 
+    def test_checkboxinput_zero(self):
+        """ CheckboxInput.value_from_datadict should return True when passed
+        '0', rather than returning the literal '0' which will get treated as
+        False by BooleanField.to_python().
+        """
+        w = CheckboxInput()
+        value = w.value_from_datadict({'flag': '0'}, {}, 'flag')
+        self.assertTrue(isinstance(value, bool))
+        self.assertTrue(value)
+
     def test_select(self):
         w = Select()
         self.assertEqual(w.render('beatle', 'J', choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), """<select name="beatle">
