Index: django/newforms/fields.py
===================================================================
--- django/newforms/fields.py	(revision 4218)
+++ django/newforms/fields.py	(working copy)
@@ -33,8 +33,8 @@
     # Tracks each time a Field instance is created. Used to retain order.
     creation_counter = 0
 
-    def __init__(self, required=True, widget=None, label=None):
-        self.required, self.label = required, label
+    def __init__(self, required=True, widget=None, label=None, default=None):
+        self.required, self.label, self.default = required, label, default
         widget = widget or self.widget
         if isinstance(widget, type):
             widget = widget()
@@ -57,8 +57,11 @@
 
         Raises ValidationError for any errors.
         """
-        if self.required and value in EMPTY_VALUES:
-            raise ValidationError(gettext(u'This field is required.'))
+        if value in EMPTY_VALUES:
+            if self.required:
+                raise ValidationError(gettext(u'This field is required.'))
+            else:
+                value = self.default
         return value
 
     def widget_attrs(self, widget):
@@ -70,17 +73,15 @@
         return {}
 
 class CharField(Field):
-    def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None):
+    def __init__(self, max_length=None, min_length=None, required=True, widget=None, label=None, default=u''):
         self.max_length, self.min_length = max_length, min_length
-        Field.__init__(self, required, widget, label)
+        Field.__init__(self, required, widget, label, default)
 
     def clean(self, value):
         "Validates max_length and min_length. Returns a Unicode object."
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         if value in EMPTY_VALUES:
-            value = u''
-            if not self.required:
-                return value
+            return value
         value = smart_unicode(value)
         if self.max_length is not None and len(value) > self.max_length:
             raise ValidationError(gettext(u'Ensure this value has at most %d characters.') % self.max_length)
@@ -93,17 +94,17 @@
             return {'maxlength': str(self.max_length)}
 
 class IntegerField(Field):
-    def __init__(self, max_value=None, min_value=None, required=True, widget=None, label=None):
+    def __init__(self, max_value=None, min_value=None, required=True, widget=None, label=None, default=u''):
         self.max_value, self.min_value = max_value, min_value
-        Field.__init__(self, required, widget, label)
+        Field.__init__(self, required, widget, label, default)
 
     def clean(self, value):
         """
         Validates that int() can be called on the input. Returns the result
         of int().
         """
-        super(IntegerField, self).clean(value)
-        if not self.required and value in EMPTY_VALUES:
+        value = Field.clean(value)
+        if value in EMPTY_VALUES:
             return u''
         try:
             value = int(value)
@@ -124,8 +125,8 @@
 )
 
 class DateField(Field):
-    def __init__(self, input_formats=None, required=True, widget=None, label=None):
-        Field.__init__(self, required, widget, label)
+    def __init__(self, input_formats=None, required=True, widget=None, label=None, default=None):
+        Field.__init__(self, required, widget, label, default)
         self.input_formats = input_formats or DEFAULT_DATE_INPUT_FORMATS
 
     def clean(self, value):
@@ -133,7 +134,7 @@
         Validates that the input can be converted to a date. Returns a Python
         datetime.date object.
         """
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         if value in EMPTY_VALUES:
             return None
         if isinstance(value, datetime.datetime):
@@ -153,8 +154,8 @@
 )
 
 class TimeField(Field):
-    def __init__(self, input_formats=None, required=True, widget=None, label=None):
-        Field.__init__(self, required, widget, label)
+    def __init__(self, input_formats=None, required=True, widget=None, label=None, default=None):
+        Field.__init__(self, required, widget, label, default)
         self.input_formats = input_formats or DEFAULT_TIME_INPUT_FORMATS
 
     def clean(self, value):
@@ -162,7 +163,7 @@
         Validates that the input can be converted to a time. Returns a Python
         datetime.time object.
         """
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         if value in EMPTY_VALUES:
             return None
         if isinstance(value, datetime.time):
@@ -187,8 +188,8 @@
 )
 
 class DateTimeField(Field):
-    def __init__(self, input_formats=None, required=True, widget=None, label=None):
-        Field.__init__(self, required, widget, label)
+    def __init__(self, input_formats=None, required=True, widget=None, label=None, default=None):
+        Field.__init__(self, required, widget, label, default)
         self.input_formats = input_formats or DEFAULT_DATETIME_INPUT_FORMATS
 
     def clean(self, value):
@@ -196,7 +197,7 @@
         Validates that the input can be converted to a datetime. Returns a
         Python datetime.datetime object.
         """
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         if value in EMPTY_VALUES:
             return None
         if isinstance(value, datetime.datetime):
@@ -211,13 +212,13 @@
         raise ValidationError(gettext(u'Enter a valid date/time.'))
 
 class RegexField(Field):
-    def __init__(self, regex, error_message=None, required=True, widget=None, label=None):
+    def __init__(self, regex, error_message=None, required=True, widget=None, label=None, default=u''):
         """
         regex can be either a string or a compiled regular expression object.
         error_message is an optional error message to use, if
         'Enter a valid value' is too generic for you.
         """
-        Field.__init__(self, required, widget, label)
+        Field.__init__(self, required, widget, label, default)
         if isinstance(regex, basestring):
             regex = re.compile(regex)
         self.regex = regex
@@ -228,8 +229,7 @@
         Validates that the input matches the regular expression. Returns a
         Unicode object.
         """
-        Field.clean(self, value)
-        if value in EMPTY_VALUES: value = u''
+        value = Field.clean(self, value)
         value = smart_unicode(value)
         if not self.required and value == u'':
             return value
@@ -243,8 +243,8 @@
     r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
 
 class EmailField(RegexField):
-    def __init__(self, required=True, widget=None, label=None):
-        RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget, label)
+    def __init__(self, required=True, widget=None, label=None, default=u''):
+        RegexField.__init__(self, email_re, gettext(u'Enter a valid e-mail address.'), required, widget, label, default)
 
 url_re = re.compile(
     r'^https?://' # http:// or https://
@@ -260,15 +260,15 @@
     URL_VALIDATOR_USER_AGENT = 'Django (http://www.djangoproject.com/)'
 
 class URLField(RegexField):
-    def __init__(self, required=True, verify_exists=False, widget=None, label=None,
+    def __init__(self, required=True, verify_exists=False, widget=None, label=None, default=u'',
             validator_user_agent=URL_VALIDATOR_USER_AGENT):
-        RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget, label)
+        RegexField.__init__(self, url_re, gettext(u'Enter a valid URL.'), required, widget, label, default)
         self.verify_exists = verify_exists
         self.user_agent = validator_user_agent
 
     def clean(self, value):
         value = RegexField.clean(self, value)
-        if self.verify_exists:
+        if self.required and self.verify_exists:
             import urllib2
             from django.conf import settings
             headers = {
@@ -292,14 +292,14 @@
 
     def clean(self, value):
         "Returns a Python boolean object."
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         return bool(value)
 
 class ChoiceField(Field):
-    def __init__(self, choices=(), required=True, widget=Select, label=None):
+    def __init__(self, choices=(), required=True, widget=Select, label=None, default=u''):
         if isinstance(widget, type):
             widget = widget(choices=choices)
-        Field.__init__(self, required, widget, label)
+        Field.__init__(self, required, widget, label, default)
         self.choices = choices
 
     def clean(self, value):
@@ -307,7 +307,6 @@
         Validates that the input is in self.choices.
         """
         value = Field.clean(self, value)
-        if value in EMPTY_VALUES: value = u''
         value = smart_unicode(value)
         if not self.required and value == u'':
             return value
@@ -317,8 +316,8 @@
         return value
 
 class MultipleChoiceField(ChoiceField):
-    def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None):
-        ChoiceField.__init__(self, choices, required, widget, label)
+    def __init__(self, choices=(), required=True, widget=SelectMultiple, label=None, default=[]):
+        ChoiceField.__init__(self, choices, required, widget, label, default)
 
     def clean(self, value):
         """
@@ -327,7 +326,7 @@
         if self.required and not value:
             raise ValidationError(gettext(u'This field is required.'))
         elif not self.required and not value:
-            return []
+            return self.default
         if not isinstance(value, (list, tuple)):
             raise ValidationError(gettext(u'Enter a list of values.'))
         new_value = []
@@ -342,8 +341,8 @@
         return new_value
 
 class ComboField(Field):
-    def __init__(self, fields=(), required=True, widget=None, label=None):
-        Field.__init__(self, required, widget, label)
+    def __init__(self, fields=(), required=True, widget=None, label=None, default=None):
+        Field.__init__(self, required, widget, label, default)
         # Set 'required' to False on the individual fields, because the
         # required validation will be handled by ComboField, not by those
         # individual fields.
@@ -356,7 +355,7 @@
         Validates the given value against all of self.fields, which is a
         list of Field instances.
         """
-        Field.clean(self, value)
+        value = Field.clean(self, value)
         for field in self.fields:
             value = field.clean(value)
         return value
