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:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user