Index: django/db/models/fields/__init__.py =================================================================== --- django/db/models/fields/__init__.py (revision 4722) +++ django/db/models/fields/__init__.py (working copy) @@ -662,6 +662,11 @@ else: func(new_data[upload_field_name]["filename"], new_data[upload_field_name]["content"], save) + def formfield_save_file(self, field_name, new_data, new_object, save=True): + if new_data[field_name]: + func = getattr(new_object, 'save_%s_file' % self.name) + func(new_data[field_name]["filename"], new_data[field_name]["content"], save) + def get_directory_name(self): return os.path.normpath(datetime.datetime.now().strftime(self.upload_to)) @@ -670,6 +675,11 @@ f = os.path.join(self.get_directory_name(), get_valid_filename(os.path.basename(filename))) return os.path.normpath(f) + def formfield(self, **kwargs): + defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} + defaults.update(kwargs) + return forms.FileField(**defaults) + class FilePathField(Field): def __init__(self, verbose_name=None, name=None, path='', match=None, recursive=False, **kwargs): self.path, self.match, self.recursive = path, match, recursive @@ -716,6 +726,11 @@ setattr(new_object, self.height_field, getattr(original_object, self.height_field)) new_object.save() + def formfield(self, **kwargs): + defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'widget': forms.FileInput} + defaults.update(kwargs) + return forms.ImageField(**defaults) + class IntegerField(Field): empty_strings_allowed = False def get_manipulator_field_objs(self): Index: django/newforms/models.py =================================================================== --- django/newforms/models.py (revision 4722) +++ django/newforms/models.py (working copy) @@ -18,6 +18,7 @@ This method is created for any form_for_model Form. """ + from django.db import models if self.errors: raise ValueError("The %s could not be created because the data didn't validate." % self._model._meta.object_name) return save_instance(self, self._model(), commit) @@ -36,9 +37,18 @@ raise ValueError("The %s could not be changed because the data didn't validate." % opts.object_name) clean_data = form.clean_data for f in opts.fields: - if not f.editable or isinstance(f, models.AutoField): - continue - setattr(instance, f.name, clean_data[f.name]) + if clean_data.has_key(f.name): + if not f.editable or isinstance(f, models.AutoField): + continue + if isinstance(f, models.FileField): + continue + setattr(instance, f.name, clean_data[f.name]) + + # FileField may need more info to save to specific paths + for f in opts.fields: + if isinstance(f, models.FileField) and clean_data.has_key(f.name): + f.formfield_save_file(f.name, clean_data, instance, save=False) + if commit: instance.save() for f in opts.many_to_many: @@ -87,6 +97,7 @@ takes a database Field instance, plus **kwargs, and returns a form Field instance with the given kwargs (i.e. 'initial'). """ + from django.db import models model = instance.__class__ opts = model._meta field_list = [] @@ -96,6 +107,10 @@ current_value = f.value_from_object(instance) formfield = formfield_callback(f, initial=current_value) if formfield: + # FileFields are only required once, because we cannot print the + # existing data into the