Ticket #10044: 10044.diff
File 10044.diff, 4.8 KB (added by , 16 years ago) |
---|
-
django/db/models/fields/files.py
1 import copy 1 2 import datetime 2 3 import os 3 4 … … 21 22 self.storage = field.storage 22 23 self._name = name or u'' 23 24 self._closed = False 25 self._committed = True 24 26 25 27 def __eq__(self, other): 26 28 # Older code may be expecting FileField values to be simple strings. … … 79 81 80 82 # Update the filesize cache 81 83 self._size = len(content) 84 self._committed = True 82 85 83 86 # Save the object because it has changed, unless save is False 84 87 if save: … … 100 103 # Delete the filesize cache 101 104 if hasattr(self, '_size'): 102 105 del self._size 106 self._committed = False 103 107 104 108 if save: 105 109 self.instance.save() … … 110 114 # it's attached to in order to work properly, but the only necessary 111 115 # data to be pickled is the file's name itself. Everything else will 112 116 # be restored later, by FileDescriptor below. 113 return {'_name': self.name, '_closed': False }117 return {'_name': self.name, '_closed': False, '_committed': True} 114 118 115 119 class FileDescriptor(object): 116 120 def __init__(self, field): … … 120 124 if instance is None: 121 125 raise AttributeError, "%s can only be accessed from %s instances." % (self.field.name(self.owner.__name__)) 122 126 file = instance.__dict__[self.field.name] 123 if not isinstance(file, FieldFile):127 if isinstance(file, basestring) or file is None: 124 128 # Create a new instance of FieldFile, based on a given file name 125 129 instance.__dict__[self.field.name] = self.field.attr_class(instance, self.field, file) 126 elif not hasattr(file, 'field'): 130 elif isinstance(file, File) and not isinstance(file, FieldFile): 131 # Other types of files may be assigned as well, but they need to 132 # have the FieldFile interface added to them 133 file_copy = copy.copy(file) 134 file_copy.__class__ = type(file.__class__.__name__, 135 (file.__class__, FieldFile), {}) 136 file_copy.instance = instance 137 file_copy.field = self.field 138 file_copy.storage = self.field.storage 139 file_copy._committed = False 140 instance.__dict__[self.field.name] = file_copy 141 elif isinstance(file, FieldFile) and not hasattr(file, 'field'): 127 142 # The FieldFile was pickled, so some attributes need to be reset. 128 143 file.instance = instance 129 144 file.field = self.field … … 164 179 return None 165 180 return unicode(value) 166 181 182 def pre_save(self, model_instance, add): 183 "Returns field's value just before saving." 184 file = super(FileField, self).pre_save(model_instance, add) 185 if file and not file._committed: 186 # Commit the file to storage prior to saving the model 187 file.save(file.name, file, save=False) 188 return file 189 167 190 def contribute_to_class(self, cls, name): 168 191 super(FileField, self).contribute_to_class(cls, name) 169 192 setattr(cls, self.name, FileDescriptor(self)) -
django/core/files/base.py
32 32 return self.size 33 33 34 34 def _get_name(self): 35 if not hasattr(self, '_name'): 36 raise ValueError("This operation requires the file to have a name.") 35 37 return self._name 36 38 name = property(_get_name) 37 39 -
tests/modeltests/files/models.py
9 9 import tempfile 10 10 from django.db import models 11 11 from django.core.files.base import ContentFile 12 from django.core.files.uploadedfile import SimpleUploadedFile 12 13 from django.core.files.storage import FileSystemStorage 13 14 from django.core.cache import cache 14 15 … … 54 55 >>> obj1.normal.read() 55 56 'content' 56 57 58 # File objects can be assigned to FileField attributes, but shouldn't get 59 # committed until the model it's attached to is saved. 60 61 >>> obj1.normal = SimpleUploadedFile('assignment.txt', 'content') 62 >>> temp_storage.listdir('tests') 63 ([], [u'default.txt', u'django_test.txt']) 64 >>> obj1.save() 65 >>> temp_storage.listdir('tests') 66 ([], [u'assignment.txt', u'default.txt', u'django_test.txt']) 67 57 68 # Files can be read in a little at a time, if necessary. 58 69 59 70 >>> obj1.normal.open()