Code

Ticket #14039: 14039_r13760.diff

File 14039_r13760.diff, 3.5 KB (added by carljm, 4 years ago)
Line 
1diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
2index 3c58873..c2e5695 100644
3--- a/django/db/models/fields/__init__.py
4+++ b/django/db/models/fields/__init__.py
5@@ -65,6 +65,8 @@ class Field(object):
6         'blank': _(u'This field cannot be blank.'),
7     }
8 
9+    defer_save = False # If true, defer saving until after other fields.
10+   
11     # Generic field type description, usually overriden by subclasses
12     def _description(self):
13         return _(u'Field of type: %(field_type)s') % {
14diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py
15index 6dfeddb..c592993 100644
16--- a/django/db/models/fields/files.py
17+++ b/django/db/models/fields/files.py
18@@ -217,6 +217,8 @@ class FileField(Field):
19     # The descriptor to use for accessing the attribute off of the class.
20     descriptor_class = FileDescriptor
21 
22+    defer_save = True
23+
24     description = ugettext_lazy("File path")
25 
26     def __init__(self, verbose_name=None, name=None, upload_to='', storage=None, **kwargs):
27diff --git a/django/forms/fields.py b/django/forms/fields.py
28index de14a5c..7a1e55e 100644
29--- a/django/forms/fields.py
30+++ b/django/forms/fields.py
31@@ -65,6 +65,7 @@ class Field(object):
32         'required': _(u'This field is required.'),
33         'invalid': _(u'Enter a valid value.'),
34     }
35+    clean_takes_initial = False # If true, clean() takes initial value as well as data.
36 
37     # Tracks each time a Field instance is created. Used to retain order.
38     creation_counter = 0
39@@ -442,6 +443,8 @@ class FileField(Field):
40         'max_length': _(u'Ensure this filename has at most %(max)d characters (it has %(length)d).'),
41     }
42 
43+    clean_takes_initial = True
44+
45     def __init__(self, *args, **kwargs):
46         self.max_length = kwargs.pop('max_length', None)
47         super(FileField, self).__init__(*args, **kwargs)
48diff --git a/django/forms/forms.py b/django/forms/forms.py
49index 7b2bc66..bcbe305 100644
50--- a/django/forms/forms.py
51+++ b/django/forms/forms.py
52@@ -277,7 +277,7 @@ class BaseForm(StrAndUnicode):
53             # widgets split data over several HTML fields.
54             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
55             try:
56-                if isinstance(field, FileField):
57+                if field.clean_takes_initial:
58                     initial = self.initial.get(name, field.initial)
59                     value = field.clean(value, initial)
60                 else:
61diff --git a/django/forms/models.py b/django/forms/models.py
62index cf465ad..c749cc4 100644
63--- a/django/forms/models.py
64+++ b/django/forms/models.py
65@@ -35,7 +35,7 @@ def construct_instance(form, instance, fields=None, exclude=None):
66     opts = instance._meta
67 
68     cleaned_data = form.cleaned_data
69-    file_field_list = []
70+    deferred_list = []
71     for f in opts.fields:
72         if not f.editable or isinstance(f, models.AutoField) \
73                 or not f.name in cleaned_data:
74@@ -46,12 +46,12 @@ def construct_instance(form, instance, fields=None, exclude=None):
75             continue
76         # Defer saving file-type fields until after the other fields, so a
77         # callable upload_to can use the values from other fields.
78-        if isinstance(f, models.FileField):
79-            file_field_list.append(f)
80+        if f.defer_save:
81+            deferred_list.append(f)
82         else:
83             f.save_form_data(instance, cleaned_data[f.name])
84 
85-    for f in file_field_list:
86+    for f in deferred_list:
87         f.save_form_data(instance, cleaned_data[f.name])
88 
89     return instance