mirror of https://github.com/django/django.git
Fixed #15644 -- Improved Django File wrapper to support more file-like objects. Thanks nickname123 and Michael Palumbo for working on the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@17871 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5e047ed859
commit
5c954136ea
|
@ -36,8 +36,13 @@ class File(FileProxyMixin):
|
|||
if not hasattr(self, '_size'):
|
||||
if hasattr(self.file, 'size'):
|
||||
self._size = self.file.size
|
||||
elif os.path.exists(self.file.name):
|
||||
elif hasattr(self.file, 'name') and os.path.exists(self.file.name):
|
||||
self._size = os.path.getsize(self.file.name)
|
||||
elif hasattr(self.file, 'tell') and hasattr(self.file, 'seek'):
|
||||
pos = self.file.tell()
|
||||
self.file.seek(0, os.SEEK_END)
|
||||
self._size = self.file.tell()
|
||||
self.file.seek(pos)
|
||||
else:
|
||||
raise AttributeError("Unable to determine the file's size.")
|
||||
return self._size
|
||||
|
@ -61,12 +66,12 @@ class File(FileProxyMixin):
|
|||
|
||||
if hasattr(self, 'seek'):
|
||||
self.seek(0)
|
||||
# Assume the pointer is at zero...
|
||||
counter = self.size
|
||||
|
||||
while counter > 0:
|
||||
yield self.read(chunk_size)
|
||||
counter -= chunk_size
|
||||
while True:
|
||||
data = self.read(chunk_size)
|
||||
if not data:
|
||||
break
|
||||
yield data
|
||||
|
||||
def multiple_chunks(self, chunk_size=None):
|
||||
"""
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import absolute_import
|
||||
|
||||
import errno
|
||||
import os
|
||||
import shutil
|
||||
|
@ -17,12 +19,13 @@ except ImportError:
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import SuspiciousOperation, ImproperlyConfigured
|
||||
from django.core.files.base import ContentFile
|
||||
from django.core.files.base import File, ContentFile
|
||||
from django.core.files.images import get_image_dimensions
|
||||
from django.core.files.storage import FileSystemStorage, get_storage_class
|
||||
from django.core.files.uploadedfile import UploadedFile
|
||||
from django.test import SimpleTestCase
|
||||
from django.utils import unittest
|
||||
from ..servers.tests import LiveServerBase
|
||||
|
||||
# Try to import PIL in either of the two ways it can end up installed.
|
||||
# Checking for the existence of Image is enough for CPython, but
|
||||
|
@ -544,6 +547,42 @@ class ContentFileTestCase(unittest.TestCase):
|
|||
def test_content_file_default_name(self):
|
||||
self.assertEqual(ContentFile("content").name, None)
|
||||
|
||||
def test_content_file_custome_name(self):
|
||||
def test_content_file_custom_name(self):
|
||||
name = "I can have a name too!"
|
||||
self.assertEqual(ContentFile("content", name=name).name, name)
|
||||
|
||||
class NoNameFileTestCase(unittest.TestCase):
|
||||
"""
|
||||
Other examples of unnamed files may be tempfile.SpooledTemporaryFile or
|
||||
urllib.urlopen()
|
||||
"""
|
||||
def test_noname_file_default_name(self):
|
||||
self.assertEqual(File(StringIO('A file with no name')).name, None)
|
||||
|
||||
def test_noname_file_get_size(self):
|
||||
self.assertEqual(File(StringIO('A file with no name')).size, 19)
|
||||
|
||||
class FileLikeObjectTestCase(LiveServerBase):
|
||||
"""
|
||||
Test file-like objects (#15644).
|
||||
"""
|
||||
def setUp(self):
|
||||
self.temp_dir = tempfile.mkdtemp()
|
||||
self.storage = FileSystemStorage(location=self.temp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
shutil.rmtree(self.temp_dir)
|
||||
|
||||
def test_urllib2_urlopen(self):
|
||||
"""
|
||||
Test the File storage API with a file like object coming from urllib2.urlopen()
|
||||
"""
|
||||
|
||||
file_like_object = self.urlopen('/example_view/')
|
||||
f = File(file_like_object)
|
||||
stored_filename = self.storage.save("remote_file.html", f)
|
||||
|
||||
stored_file = self.storage.open(stored_filename)
|
||||
remote_file = self.urlopen('/example_view/')
|
||||
|
||||
self.assertEqual(stored_file.read(), remote_file.read())
|
||||
|
|
Loading…
Reference in New Issue