1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #10404: ImageField height_field and width_field options no longer depend on putting the image field after the height/width fields as they did after r9766.

This bug actually exposed a related handful of inconsistancies in the underlying file handling and wraping, so a few related changes are in here as well:

    * Dimensions are also now calculated the moment the image is assigned to the field instead of upon save.
    * The base `File` object now when possible delegates its closed attribute down to the os-level file it wrapps.
    * In-memory files' `close()` now is a no-op. Without this certain APIs that should be able to handle in-memory files were failing.
    * Accessing `FieldFile.closed` used to open the file. That's silly, and it doesn't any more.
    * Some over-eager error handling was squishing some errors that would normally be raised. One unit test was incorrectly depending on this behavior, so the test was removed.

Thanks to Armin Ronacher for much of this work.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@10737 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Jacob Kaplan-Moss
2009-05-11 09:57:19 +00:00
parent 4f9fd44965
commit 2b0903b2c4
6 changed files with 139 additions and 48 deletions

View File

@@ -16,7 +16,6 @@ class File(FileProxyMixin):
name = getattr(file, 'name', None)
self.name = name
self.mode = getattr(file, 'mode', None)
self.closed = False
def __str__(self):
return smart_str(self.name or '')
@@ -48,6 +47,10 @@ class File(FileProxyMixin):
size = property(_get_size, _set_size)
def _get_closed(self):
return not self.file or self.file.closed
closed = property(_get_closed)
def chunks(self, chunk_size=None):
"""
Read the file and yield chucks of ``chunk_size`` bytes (defaults to
@@ -101,15 +104,13 @@ class File(FileProxyMixin):
def open(self, mode=None):
if not self.closed:
self.seek(0)
elif os.path.exists(self.file.name):
self.file = open(self.file.name, mode or self.file.mode)
self.closed = False
elif self.name and os.path.exists(self.name):
self.file = open(self.name, mode or self.mode)
else:
raise ValueError("The file cannot be reopened.")
def close(self):
self.file.close()
self.closed = True
class ContentFile(File):
"""
@@ -127,6 +128,7 @@ class ContentFile(File):
return True
def open(self, mode=None):
if self.closed:
self.closed = False
self.seek(0)
def close(self):
pass

View File

@@ -21,7 +21,11 @@ class ImageFile(File):
def _get_image_dimensions(self):
if not hasattr(self, '_dimensions_cache'):
close = self.closed
self.open()
self._dimensions_cache = get_image_dimensions(self)
if close:
self.close()
return self._dimensions_cache
def get_image_dimensions(file_or_path):

View File

@@ -74,16 +74,13 @@ class TemporaryUploadedFile(UploadedFile):
def close(self):
try:
try:
return self.file.close()
except OSError, e:
if e.errno != 2:
# Means the file was moved or deleted before the tempfile
# could unlink it. Still sets self.file.close_called and
# calls self.file.file.close() before the exception
raise
finally:
self.closed = True
return self.file.close()
except OSError, e:
if e.errno != 2:
# Means the file was moved or deleted before the tempfile
# could unlink it. Still sets self.file.close_called and
# calls self.file.file.close() before the exception
raise
class InMemoryUploadedFile(UploadedFile):
"""
@@ -93,10 +90,12 @@ class InMemoryUploadedFile(UploadedFile):
super(InMemoryUploadedFile, self).__init__(file, name, content_type, size, charset)
self.field_name = field_name
def open(self):
self.closed = False
def open(self, mode=None):
self.file.seek(0)
def close(self):
pass
def chunks(self, chunk_size=None):
self.file.seek(0)
yield self.read()