mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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:
		| @@ -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()) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user