diff --git a/django/forms/fields.py b/django/forms/fields.py
index 113a5aa..ea9e6dc 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -54,7 +54,7 @@ class Field(object):
 
     def __init__(self, required=True, widget=None, label=None, initial=None,
                  help_text=None, error_messages=None, show_hidden_initial=False,
-                 validators=[], localize=False):
+                 validators=[], localize=False, normalize=None):
         # required -- Boolean that specifies whether the field is required.
         #             True by default.
         # widget -- A Widget class, or instance of a Widget class, that should
@@ -82,6 +82,7 @@ class Field(object):
             self.help_text = u''
         else:
             self.help_text = smart_unicode(help_text)
+        self.normalize = normalize
         widget = widget or self.widget
         if isinstance(widget, type):
             widget = widget()
@@ -149,6 +150,8 @@ class Field(object):
         Raises ValidationError for any errors.
         """
         value = self.to_python(value)
+        if self.normalize:
+            value = self.normalize(value)
         self.validate(value)
         self.run_validators(value)
         return value
@@ -186,6 +189,8 @@ class CharField(Field):
             self.validators.append(validators.MinLengthValidator(min_length))
         if max_length is not None:
             self.validators.append(validators.MaxLengthValidator(max_length))
+        if self.normalize is None:
+            self.normalize = lambda value: value.strip()
 
     def to_python(self, value):
         "Returns a Unicode object."
@@ -427,7 +432,7 @@ class DateTimeField(BaseTemporalField):
         return datetime.datetime.strptime(value, format)
 
 class RegexField(CharField):
-    def __init__(self, regex, max_length=None, min_length=None, error_message=None, *args, **kwargs):
+    def __init__(self, regex, max_length=None, min_length=None, error_message=None, normalize=False,  *args, **kwargs):
         """
         regex can be either a string or a compiled regular expression object.
         error_message is an optional error message to use, if
@@ -438,7 +443,7 @@ class RegexField(CharField):
             error_messages = kwargs.get('error_messages') or {}
             error_messages['invalid'] = error_message
             kwargs['error_messages'] = error_messages
-        super(RegexField, self).__init__(max_length, min_length, *args, **kwargs)
+        super(RegexField, self).__init__(max_length, min_length, normalize=normalize, *args, **kwargs)
         if isinstance(regex, basestring):
             regex = re.compile(regex)
         self.regex = regex
@@ -450,10 +455,6 @@ class EmailField(CharField):
     }
     default_validators = [validators.validate_email]
 
-    def clean(self, value):
-        value = self.to_python(value).strip()
-        return super(EmailField, self).clean(value)
-
 class FileField(Field):
     widget = ClearableFileInput
     default_error_messages = {
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 66c05e5..c4df0ba 100644
--- a/docs/ref/forms/fields.txt
+++ b/docs/ref/forms/fields.txt
@@ -278,6 +278,29 @@ as the rendered output.
 See the :ref:`format localization <format-localization>` documentation for
 more information.
 
+``normalize``
+~~~~~~~~~~~~
+
+.. versionadded:: New in Django development version
+
+.. attribute:: Field.normalize
+
+The ``normalize`` argument lets you normalize the input data before it is validated.
+A common use-case is stripping leading and trailinig whitespace from CharFields::
+
+    >>> foo = forms.CharField(normalize=lambda x: x.strip())
+    >>> foo.clean('   ')
+    Traceback (most recent call last):
+      ...
+    ValidationError: [u'This field is required.']
+
+This behavior for CharField enabled by default. Set `normalize=False`` to disable it.
+
+    >>> foo = forms.CharField(normalize=False)
+    >>> foo.clean('   ')
+    u'   '
+
+
 .. _built-in fields:
 
 Built-in ``Field`` classes
@@ -317,7 +340,9 @@ For each field, we describe the default widget used if you don't specify
 
     * Default widget: ``TextInput``
     * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
+    * Normalizes to: A Unicode object with stripped leading and trailinig whitespace.
+      Set ``normalize=False`` to disable stripping spaces or set
+      ``normilize=your_callable_name`` to change normalization behavior.
     * Validates ``max_length`` or ``min_length``, if they are provided.
       Otherwise, all inputs are valid.
     * Error message keys: ``required``, ``max_length``, ``min_length``
@@ -481,8 +506,10 @@ Takes four optional arguments:
 
     * Default widget: ``TextInput``
     * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value is a valid email address, using a
+    * Normalizes to: A Unicode object with stripped leading and trailinig whitespace.
+      Set ``normalize=False`` to disable stripping spaces or set
+      ``normilize=your_callable_name`` to change normalization behavior.
+    * Validates that the given value is a valid e-mail address, using a
       moderately complex regular expression.
     * Error message keys: ``required``, ``invalid``
 
@@ -618,7 +645,9 @@ Takes two optional arguments for validation:
 
     * Default widget: ``TextInput``
     * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
+    * Normalizes to: A Unicode object with stripped leading and trailinig whitespace.
+      Set ``normalize=False`` to disable stripping spaces or set
+      ``normilize=your_callable_name`` to change normalization behavior.
     * Validates that the given value is a valid IPv4 address, using a regular
       expression.
     * Error message keys: ``required``, ``invalid``
@@ -746,7 +775,9 @@ and the error message as the value.
 
    * Default widget: ``TextInput``
    * Empty value: ``''`` (an empty string)
-   * Normalizes to: A Unicode object.
+    * Normalizes to: A Unicode object with stripped leading and trailinig whitespace.
+      Set ``normalize=False`` to disable stripping spaces or set
+      ``normilize=your_callable_name`` to change normalization behavior.
    * Validates that the given value contains only letters, numbers,
      underscores, and hyphens.
    * Error messages: ``required``, ``invalid``
@@ -785,7 +816,9 @@ If no ``input_formats`` argument is provided, the default input formats are::
 
     * Default widget: ``TextInput``
     * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
+    * Normalizes to: A Unicode object with stripped leading and trailinig whitespace.
+      Set ``normalize=False`` to disable stripping spaces or set
+      ``normilize=your_callable_name`` to change normalization behavior.
     * Validates that the given value is a valid URL.
     * Error message keys: ``required``, ``invalid``, ``invalid_link``
 
diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
index 6780413..1dcff0d 100644
--- a/tests/regressiontests/forms/tests/fields.py
+++ b/tests/regressiontests/forms/tests/fields.py
@@ -131,6 +131,14 @@ class FieldsTests(TestCase):
         self.assertEqual(f.max_length, None)
         self.assertEqual(f.min_length, 10)
 
+    def test_charfield_normalize(self):
+        f = CharField()
+        self.assertRaisesErrorWithMessage(ValidationError, "[u'This field is required.']", f.clean, "  \t")
+
+    def test_charfield_normalize_false(self):
+        f = CharField(normalize=False)
+        self.assertEqual("  \t", f.clean("  \t"))
+
     # IntegerField ################################################################
 
     def test_integerfield_1(self):
