diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 3c58873..c2e5695 100644
|
a
|
b
|
class Field(object):
|
| 65 | 65 | 'blank': _(u'This field cannot be blank.'), |
| 66 | 66 | } |
| 67 | 67 | |
| | 68 | defer_save = False # If true, defer saving until after other fields. |
| | 69 | |
| 68 | 70 | # Generic field type description, usually overriden by subclasses |
| 69 | 71 | def _description(self): |
| 70 | 72 | 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
|
b
|
class FileField(Field):
|
| 217 | 217 | # The descriptor to use for accessing the attribute off of the class. |
| 218 | 218 | descriptor_class = FileDescriptor |
| 219 | 219 | |
| | 220 | defer_save = True |
| | 221 | |
| 220 | 222 | description = ugettext_lazy("File path") |
| 221 | 223 | |
| 222 | 224 | 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
|
b
|
class Field(object):
|
| 65 | 65 | 'required': _(u'This field is required.'), |
| 66 | 66 | 'invalid': _(u'Enter a valid value.'), |
| 67 | 67 | } |
| | 68 | clean_takes_initial = False # If true, clean() takes initial value as well as data. |
| 68 | 69 | |
| 69 | 70 | # Tracks each time a Field instance is created. Used to retain order. |
| 70 | 71 | creation_counter = 0 |
| … |
… |
class FileField(Field):
|
| 442 | 443 | 'max_length': _(u'Ensure this filename has at most %(max)d characters (it has %(length)d).'), |
| 443 | 444 | } |
| 444 | 445 | |
| | 446 | clean_takes_initial = True |
| | 447 | |
| 445 | 448 | def __init__(self, *args, **kwargs): |
| 446 | 449 | self.max_length = kwargs.pop('max_length', None) |
| 447 | 450 | super(FileField, self).__init__(*args, **kwargs) |
| … |
… |
class MultiValueField(Field):
|
| 733 | 736 | "compressed" version of those values -- a single value. |
| 734 | 737 | |
| 735 | 738 | You'll probably want to use this with MultiWidget. |
| | 739 | |
| | 740 | If your MultiValueField subclass includes a FileField or derivative as one |
| | 741 | of its fields, there will be subtle differences in behavior (particularly |
| | 742 | displaying a bound form with initial data) unless you set your subclasses' |
| | 743 | ``clean_takes_initial`` attribute to True and override the clean() method |
| | 744 | to accept an ``initial`` arg and pass it (or an appropriate part of it) on |
| | 745 | to the member FileField. |
| 736 | 746 | """ |
| 737 | 747 | default_error_messages = { |
| 738 | 748 | 'invalid': _(u'Enter a list of values.'), |
diff --git a/django/forms/forms.py b/django/forms/forms.py
index 7b2bc66..bcbe305 100644
|
a
|
b
|
class BaseForm(StrAndUnicode):
|
| 277 | 277 | # widgets split data over several HTML fields. |
| 278 | 278 | value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) |
| 279 | 279 | try: |
| 280 | | if isinstance(field, FileField): |
| | 280 | if field.clean_takes_initial: |
| 281 | 281 | initial = self.initial.get(name, field.initial) |
| 282 | 282 | value = field.clean(value, initial) |
| 283 | 283 | else: |
diff --git a/django/forms/models.py b/django/forms/models.py
index cf465ad..c749cc4 100644
|
a
|
b
|
def construct_instance(form, instance, fields=None, exclude=None):
|
| 35 | 35 | opts = instance._meta |
| 36 | 36 | |
| 37 | 37 | cleaned_data = form.cleaned_data |
| 38 | | file_field_list = [] |
| | 38 | deferred_list = [] |
| 39 | 39 | for f in opts.fields: |
| 40 | 40 | if not f.editable or isinstance(f, models.AutoField) \ |
| 41 | 41 | or not f.name in cleaned_data: |
| … |
… |
def construct_instance(form, instance, fields=None, exclude=None):
|
| 46 | 46 | continue |
| 47 | 47 | # Defer saving file-type fields until after the other fields, so a |
| 48 | 48 | # callable upload_to can use the values from other fields. |
| 49 | | if isinstance(f, models.FileField): |
| 50 | | file_field_list.append(f) |
| | 49 | if f.defer_save: |
| | 50 | deferred_list.append(f) |
| 51 | 51 | else: |
| 52 | 52 | f.save_form_data(instance, cleaned_data[f.name]) |
| 53 | 53 | |
| 54 | | for f in file_field_list: |
| | 54 | for f in deferred_list: |
| 55 | 55 | f.save_form_data(instance, cleaned_data[f.name]) |
| 56 | 56 | |
| 57 | 57 | return instance |