Merge pull request #775 from HiddenData/ticket-18899

Fixed #18899 -- FileSystemStorage.save should support any file-like objects
This commit is contained in:
Honza Král 2013-02-23 08:04:41 -08:00
commit 129d2e8f85
2 changed files with 36 additions and 2 deletions

View File

@ -37,13 +37,17 @@ class Storage(object):
def save(self, name, content):
"""
Saves new content to the file specified by name. The content should be a
proper File object, ready to be read from the beginning.
Saves new content to the file specified by name. The content should be
a proper File object or any python file-like object, ready to be read
from the beginning.
"""
# Get the proper name for the file, as it will actually be saved.
if name is None:
name = content.name
if not hasattr(content, 'chunks'):
content = File(content)
name = self.get_available_name(name)
name = self._save(name, content)

View File

@ -2,6 +2,7 @@ from __future__ import absolute_import
import gzip
import shutil
import StringIO
import tempfile
from django.core.cache import cache
@ -102,6 +103,35 @@ class FileStorageTests(TestCase):
obj4.random.save("random_file", ContentFile("random content"))
self.assertTrue(obj4.random.name.endswith("/random_file"))
def test_file_object(self):
# Create sample file
temp_storage.save('tests/example.txt', ContentFile('some content'))
# Load it as python file object
file_obj = open(temp_storage.path('tests/example.txt'))
# Save it using storage and read its content
temp_storage.save('tests/file_obj', file_obj)
self.assertTrue(temp_storage.exists('tests/file_obj'))
self.assertEqual(
temp_storage.open('tests/file_obj').read(),
'some content')
def test_stringio(self):
# Test passing StringIO instance as content argument to save
output = StringIO.StringIO()
output.write('content')
output.seek(0)
# Save it and read written file
temp_storage.save('tests/stringio', output)
self.assertTrue(temp_storage.exists('tests/stringio'))
self.assertEqual(
temp_storage.open('tests/stringio').read(),
'content')
class FileTests(unittest.TestCase):
def test_context_manager(self):