Index: django/newforms/widgets.py
===================================================================
--- django/newforms/widgets.py	(revision 5779)
+++ django/newforms/widgets.py	(working copy)
@@ -153,6 +153,13 @@
             final_attrs['value'] = force_unicode(value) # Only add the 'value' attribute if a value is non-empty.
         return u'<input%s />' % flatatt(final_attrs)
 
+    def value_from_datadict(self, data, name):
+        if name not in data:
+            # A missing value returns False because it simply means the check
+            # box wasn't checked.
+            return False
+        return super(CheckboxInput, self).value_from_datadict(data, name)
+
 class Select(Widget):
     def __init__(self, attrs=None, choices=()):
         self.attrs = attrs or {}
Index: docs/newforms.txt
===================================================================
--- docs/newforms.txt	(revision 5779)
+++ docs/newforms.txt	(working copy)
@@ -1015,9 +1015,8 @@
 ~~~~~~~~~~~~~~~~
 
     * Default widget: ``CheckboxInput``
-    * Empty value: ``None``
+    * Empty value: ``False``
     * Normalizes to: A Python ``True`` or ``False`` value.
-    * Validates nothing (i.e., it never raises a ``ValidationError``).
 
 ``CharField``
 ~~~~~~~~~~~~~
@@ -1025,7 +1024,7 @@
     * Default widget: ``TextInput``
     * Empty value: ``''`` (an empty string)
     * Normalizes to: A Unicode object.
-    * Validates nothing, unless ``max_length`` or ``min_length`` is provided.
+    * Validates ``max_length`` and ``min_length`` if they are provided.
 
 Has two optional arguments for validation, ``max_length`` and ``min_length``.
 If provided, these arguments ensure that the string is at most or at least the
@@ -1126,7 +1125,6 @@
     * Default widget: ``NullBooleanSelect``
     * Empty value: ``None``
     * Normalizes to: A Python ``True``, ``False`` or ``None`` value.
-    * Validates nothing (i.e., it never raises a ``ValidationError``).
 
 ``RegexField``
 ~~~~~~~~~~~~~~
Index: tests/regressiontests/forms/tests.py
===================================================================
--- tests/regressiontests/forms/tests.py	(revision 5779)
+++ tests/regressiontests/forms/tests.py	(working copy)
@@ -276,6 +276,15 @@
 >>> w.render('greeting', None)
 u'<input type="checkbox" name="greeting" />'
 
+The CheckboxInput widget will return False if the key is not found in the data
+dict.
+>>> w.value_from_datadict({}, 'testing')
+False
+
+If the key *is* provided, it can still be None.
+>>> print w.value_from_datadict({'testing':None}, 'testing')
+None
+
 # Select Widget ###############################################################
 
 >>> w = Select()
