Index: django/db/models/fields/__init__.py =================================================================== --- django/db/models/fields/__init__.py (revision 4457) +++ django/db/models/fields/__init__.py (working copy) @@ -660,6 +660,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 Index: django/newforms/models.py =================================================================== --- django/newforms/models.py (revision 4457) +++ django/newforms/models.py (working copy) @@ -13,6 +13,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) @@ -33,11 +34,20 @@ for f in opts.fields: if isinstance(f, models.AutoField): continue + if isinstance(f,models.FileField): + continue setattr(instance, f.attname, clean_data[f.name]) if commit: instance.save() for f in opts.many_to_many: setattr(instance, f.attname, clean_data[f.name]) + + for f in opts.fields: + if isinstance(f, models.FileField): + file_data = clean_data[f.name][0] + if file_data is not None: + func = getattr(instance,'save_%s_file' % f.name) + func(file_data['filename'], file_data['content']) # GOTCHA: If many-to-many data is given and commit=False, the many-to-many # data will be lost. This happens because a many-to-many options cannot be # set on an object until after it's saved. Maybe we should raise an Index: django/newforms/fields.py =================================================================== --- django/newforms/fields.py (revision 4457) +++ django/newforms/fields.py (working copy) @@ -10,7 +10,7 @@ import time __all__ = ( - 'Field', 'CharField', 'IntegerField', + 'Field', 'CharField', 'FileField', 'IntegerField', 'DEFAULT_DATE_INPUT_FORMATS', 'DateField', 'DEFAULT_TIME_INPUT_FORMATS', 'TimeField', 'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', @@ -107,6 +107,14 @@ if self.max_length is not None and isinstance(widget, (TextInput, PasswordInput)): return {'maxlength': str(self.max_length)} +class FileField(Field): + def __init__(self,required=True,widget=None,label=None,initial=None): + super(FileField,self).__init__(required,widget,label,initial) + + def clean(self, value): + super(FileField,self).clean(value) + return value + class IntegerField(Field): def __init__(self, max_value=None, min_value=None, *args, **kwargs): self.max_value, self.min_value = max_value, min_value Index: django/newforms/widgets.py =================================================================== --- django/newforms/widgets.py (revision 4457) +++ django/newforms/widgets.py (working copy) @@ -107,6 +107,22 @@ class FileInput(Input): input_type = 'file' + + def render(self,name,value,attrs=None,choices=()): + if value is None: value = '' + file_attrs = self.build_attrs(attrs, type='file',name=name+'_file') + final_attrs = self.build_attrs(attrs, type='hidden', name=name) + if value != '': final_attrs['value'] = smart_unicode(value) # only add the value attribute if a value is non-empty + + if value != '': + currently = u'Currently: %s
Change: ' % smart_unicode(value) + else: + currently = u'' + + return u'%s ' % (currently,flatatt(file_attrs),flatatt(final_attrs)) + + def value_from_datadict(self,data,name): + return [data.get(name+'_file',None),data.get(name,None)] class Textarea(Widget): def render(self, name, value, attrs=None):