From 664855b74e1f417384dc7aef35a3df5f86db52d6 Mon Sep 17 00:00:00 2001 From: Marcin Biernat Date: Sat, 23 Feb 2013 13:42:04 +0100 Subject: [PATCH] #18899 FileSystemStorage.save should support any file-like objects --- django/core/files/storage.py | 8 ++++++-- tests/modeltests/files/tests.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 0b623fe7c2..89caf3675d 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -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) diff --git a/tests/modeltests/files/tests.py b/tests/modeltests/files/tests.py index 50d1915c28..8fbdbb8ff3 100644 --- a/tests/modeltests/files/tests.py +++ b/tests/modeltests/files/tests.py @@ -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):