diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 3c58873..c2e5695 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -65,6 +65,8 @@ class Field(object):
         'blank': _(u'This field cannot be blank.'),
     }
 
+    defer_save = False # If true, defer saving until after other fields.
+    
     # Generic field type description, usually overriden by subclasses
     def _description(self):
         return _(u'Field of type: %(field_type)s') % {
diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
index 6dfeddb..c592993 100644
--- a/django/db/models/fields/files.py
+++ b/django/db/models/fields/files.py
@@ -217,6 +217,8 @@ class FileField(Field):
     # The descriptor to use for accessing the attribute off of the class.
     descriptor_class = FileDescriptor
 
+    defer_save = True
+
     description = ugettext_lazy("File path")
 
     def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs):
diff --git a/django/forms/fields.py b/django/forms/fields.py
index de14a5c..3680844 100644
--- a/django/forms/fields.py
+++ b/django/forms/fields.py
@@ -65,6 +65,7 @@ class Field(object):
         'required': _(u'This field is required.'),
         'invalid': _(u'Enter a valid value.'),
     }
+    clean_takes_initial = False # If true, clean() takes initial value as well as data.
 
     # Tracks each time a Field instance is created. Used to retain order.
     creation_counter = 0
@@ -442,6 +443,8 @@ class FileField(Field):
         'max_length': _(u'Ensure this filename has at most %(max)d characters (it has %(length)d).'),
     }
 
+    clean_takes_initial = True
+
     def __init__(self, *args, **kwargs):
         self.max_length = kwargs.pop('max_length', None)
         super(FileField, self).__init__(*args, **kwargs)
@@ -733,6 +736,13 @@ class MultiValueField(Field):
     "compressed" version of those values -- a single value.
 
     You'll probably want to use this with MultiWidget.
+
+    If your MultiValueField subclass includes a FileField or derivative as one
+    of its fields, there will be subtle differences in behavior (particularly
+    displaying a bound form with initial data) unless you set your subclasses'
+    ``clean_takes_initial`` attribute to True and override the clean() method
+    to accept an ``initial`` arg and pass it (or an appropriate part of it) on
+    to the member FileField.
     """
     default_error_messages = {
         'invalid': _(u'Enter a list of values.'),
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 7b2bc66..bcbe305 100644
--- a/django/forms/forms.py
+++ b/django/forms/forms.py
@@ -277,7 +277,7 @@ class BaseForm(StrAndUnicode):
             # widgets split data over several HTML fields.
             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
             try:
-                if isinstance(field, FileField):
+                if field.clean_takes_initial:
                     initial = self.initial.get(name, field.initial)
                     value = field.clean(value, initial)
                 else:
diff --git a/django/forms/models.py b/django/forms/models.py
index cf465ad..c749cc4 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -35,7 +35,7 @@ def construct_instance(form, instance, fields=None, exclude=None):
     opts = instance._meta
 
     cleaned_data = form.cleaned_data
-    file_field_list = []
+    deferred_list = []
     for f in opts.fields:
         if not f.editable or isinstance(f, models.AutoField) \
                 or not f.name in cleaned_data:
@@ -46,12 +46,12 @@ def construct_instance(form, instance, fields=None, exclude=None):
             continue
         # Defer saving file-type fields until after the other fields, so a
         # callable upload_to can use the values from other fields.
-        if isinstance(f, models.FileField):
-            file_field_list.append(f)
+        if f.defer_save:
+            deferred_list.append(f)
         else:
             f.save_form_data(instance, cleaned_data[f.name])
 
-    for f in file_field_list:
+    for f in deferred_list:
         f.save_form_data(instance, cleaned_data[f.name])
 
     return instance
