Index: django/db/models/fields/__init__.py
===================================================================
--- django/db/models/fields/__init__.py	(revision 7020)
+++ django/db/models/fields/__init__.py	(working copy)
@@ -797,15 +797,12 @@
         return os.path.normpath(f)
 
     def save_form_data(self, instance, data):
-        if data:
+        from django.newforms.fields import UploadedFile
+        if data and isinstance(data, UploadedFile):
             getattr(instance, "save_%s_file" % self.name)(data.filename, data.content, save=False)
 
     def formfield(self, **kwargs):
         defaults = {'form_class': forms.FileField}
-        # If a file has been provided previously, then the form doesn't require
-        # that a new file is provided this time.
-        if 'initial' in kwargs:
-            defaults['required'] = False
         defaults.update(kwargs)
         return super(FileField, self).formfield(**defaults)
 
Index: django/newforms/fields.py
===================================================================
--- django/newforms/fields.py	(revision 7020)
+++ django/newforms/fields.py	(working copy)
@@ -428,6 +428,7 @@
 
 class FileField(Field):
     widget = FileInput
+    takes_initial = True
     default_error_messages = {
         'invalid': _(u"No file was submitted. Check the encoding type on the form."),
         'missing': _(u"No file was submitted."),
@@ -437,10 +438,12 @@
     def __init__(self, *args, **kwargs):
         super(FileField, self).__init__(*args, **kwargs)
 
-    def clean(self, data):
-        super(FileField, self).clean(data)
+    def clean(self, data, initial=None):
+        super(FileField, self).clean(initial or data)
         if not self.required and data in EMPTY_VALUES:
-            return None
+            return initial or None
+        elif not data and initial:
+            return initial
         try:
             f = UploadedFile(data['filename'], data['content'])
         except TypeError:
@@ -456,12 +459,12 @@
         'invalid_image': _(u"Upload a valid image. The file you uploaded was either not an image or a corrupted image."),
     }
 
-    def clean(self, data):
+    def clean(self, data, initial=None):
         """
         Checks that the file-upload field data contains a valid image (GIF, JPG,
         PNG, possibly others -- whatever the Python Imaging Library supports).
         """
-        f = super(ImageField, self).clean(data)
+        f = super(ImageField, self).clean(data, initial)
         if f is None:
             return None
         from PIL import Image
@@ -614,6 +617,8 @@
         return new_value
 
 class ComboField(Field):
+    takes_initial = True
+
     """
     A Field whose clean() method calls multiple Field clean() methods.
     """
@@ -626,14 +631,17 @@
             f.required = False
         self.fields = fields
 
-    def clean(self, value):
+    def clean(self, value, initial=None):
         """
         Validates the given value against all of self.fields, which is a
         list of Field instances.
         """
-        super(ComboField, self).clean(value)
+        super(ComboField, self).clean(initial or value)
         for field in self.fields:
-            value = field.clean(value)
+            if hasattr(field, 'takes_initial'):
+                value = field.clean(value, initial)
+            else:
+                value = field.clean(value)
         return value
 
 class MultiValueField(Field):
Index: django/newforms/forms.py
===================================================================
--- django/newforms/forms.py	(revision 7020)
+++ django/newforms/forms.py	(working copy)
@@ -182,7 +182,11 @@
             # widgets split data over several HTML fields.
             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
             try:
-                value = field.clean(value)
+                if hasattr(field, 'takes_initial'):
+                    initial = self.initial.get(name, field.initial)
+                    value = field.clean(value, initial)
+                else:
+                    value = field.clean(value)
                 self.cleaned_data[name] = value
                 if hasattr(self, 'clean_%s' % name):
                     value = getattr(self, 'clean_%s' % name)()
Index: tests/modeltests/model_forms/models.py
===================================================================
--- tests/modeltests/model_forms/models.py	(revision 7020)
+++ tests/modeltests/model_forms/models.py	(working copy)
@@ -7,6 +7,9 @@
 most of these tests should be rewritten.
 """
 
+import os
+import tempfile
+
 from django.db import models
 
 ARTICLE_STATUS = (
@@ -55,6 +58,13 @@
     def __unicode__(self):
         return self.phone
 
+class TextFile(models.Model):
+    description = models.CharField(max_length=20)
+    file = models.FileField(upload_to=tempfile.gettempdir())
+
+    def __unicode__(self):
+        return self.description
+
 __test__ = {'API_TESTS': """
 >>> from django import newforms as forms
 >>> from django.newforms.models import ModelForm
@@ -701,4 +711,75 @@
 True
 >>> f.cleaned_data
 {'phone': u'312-555-1212', 'description': u'Assistance'}
+
+# FileField ###################################################################
+
+>>> class TextFileForm(ModelForm):
+...     class Meta:
+...         model = TextFile
+
+Test conditions when files is either not given or empty.
+
+>>> f = TextFileForm(data={'description': u'Assistance'})
+>>> f.is_valid()
+False
+>>> f = TextFileForm(data={'description': u'Assistance'}, files={})
+>>> f.is_valid()
+False
+
+Upload a file and ensure it all works as expected.
+
+>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test1.txt', 'content': 'hello world'}})
+>>> f.is_valid()
+True
+>>> type(f.cleaned_data['file'])
+<class 'django.newforms.fields.UploadedFile'>
+>>> instance = f.save()
+>>> instance.file
+u'.../test1.txt'
+
+Edit an instance that already has the file defined in the model. This will not
+save the file again, but leave it exactly as it is.
+
+>>> f = TextFileForm(data={'description': u'Assistance'}, instance=instance)
+>>> f.is_valid()
+True
+>>> f.cleaned_data['file']
+u'.../test1.txt'
+>>> instance = f.save()
+>>> instance.file
+u'.../test1.txt'
+
+Delete the current file since this is not done by Django.
+
+>>> os.unlink(instance.get_file_filename())
+
+Override the file by uploading a new one.
+
+>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test2.txt', 'content': 'hello world'}}, instance=instance)
+>>> f.is_valid()
+True
+>>> instance = f.save()
+>>> instance.file
+u'.../test2.txt'
+
+>>> instance.delete()
+
+Test the non-required FileField
+
+>>> f = TextFileForm(data={'description': u'Assistance'})
+>>> f.fields['file'].required = False
+>>> f.is_valid()
+True
+>>> instance = f.save()
+>>> instance.file
+''
+
+>>> f = TextFileForm(data={'description': u'Assistance'}, files={'file': {'filename': 'test3.txt', 'content': 'hello world'}}, instance=instance)
+>>> f.is_valid()
+True
+>>> instance = f.save()
+>>> instance.file
+u'.../test3.txt'
+>>> instance.delete()
 """}
Index: tests/regressiontests/forms/fields.py
===================================================================
--- tests/regressiontests/forms/fields.py	(revision 7020)
+++ tests/regressiontests/forms/fields.py	(working copy)
@@ -749,34 +749,64 @@
 ...
 ValidationError: [u'This field is required.']
 
+>>> f.clean('', '')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f.clean('', 'files/test1.pdf')
+'files/test1.pdf'
+
 >>> f.clean(None)
 Traceback (most recent call last):
 ...
 ValidationError: [u'This field is required.']
 
+>>> f.clean(None, '')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f.clean(None, 'files/test2.pdf')
+'files/test2.pdf'
+
 >>> f.clean({})
 Traceback (most recent call last):
 ...
 ValidationError: [u'No file was submitted.']
 
+>>> f.clean({}, '')
+Traceback (most recent call last):
+...
+ValidationError: [u'No file was submitted.']
+
+>>> f.clean({}, 'files/test3.pdf')
+'files/test3.pdf'
+
 >>> f.clean('some content that is not a file')
 Traceback (most recent call last):
 ...
 ValidationError: [u'No file was submitted. Check the encoding type on the form.']
 
->>> f.clean({'filename': 'name', 'content':None})
+>>> f.clean({'filename': 'name', 'content': None})
 Traceback (most recent call last):
 ...
 ValidationError: [u'The submitted file is empty.']
 
->>> f.clean({'filename': 'name', 'content':''})
+>>> f.clean({'filename': 'name', 'content': ''})
 Traceback (most recent call last):
 ...
 ValidationError: [u'The submitted file is empty.']
 
->>> type(f.clean({'filename': 'name', 'content':'Some File Content'}))
+>>> type(f.clean({'filename': 'name', 'content': 'Some File Content'}))
 <class 'django.newforms.fields.UploadedFile'>
 
+>>> unicode(f.clean({'filename': 'name', 'content': 'Some File Content'}))
+u'name'
+
+>>> type(f.clean({'filename': 'name', 'content': 'Some File Content'}, 'files/test4.pdf'))
+<class 'django.newforms.fields.UploadedFile'>
+
 # URLField ##################################################################
 
 >>> f = URLField()
@@ -1105,6 +1135,23 @@
 u''
 >>> f.clean(None)
 u''
+>>> f = ComboField(fields=[FileField(), CharField(max_length=20)])
+>>> f.clean('data', 'some_file.txt')
+Traceback (most recent call last):
+...    
+ValidationError: [u'No file was submitted. Check the encoding type on the form.']
+>>> f.clean('', 'some_file.txt')
+u'some_file.txt'
+>>> f.clean('', None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+>>> f.clean({'filename': 'filename.txt', 'content':'something'})
+u'filename.txt'
+>>> f.clean({'filename': 'too_long_filename_for_this_combofield_here.txt', 'content':'something'})
+Traceback (most recent call last):
+...
+ValidationError: [u'Ensure this value has at most 20 characters (it has 46).']
 
 # SplitDateTimeField ##########################################################
 
