Commit 34dcf51e authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed #19367 -- Fixed saving ContentFile in filesystem storage

This was not working properly when ContentFile was initialized with
an unicode string.
Thanks Alexey Boriskin for the report and the test.
parent 553838a2
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ from io import BytesIO, StringIO, UnsupportedOperation
from django.utils.encoding import smart_text
from django.core.files.utils import FileProxyMixin
from django.utils import six
from django.utils.encoding import python_2_unicode_compatible
from django.utils.encoding import force_bytes, python_2_unicode_compatible

@python_2_unicode_compatible
class File(FileProxyMixin):
@@ -134,8 +134,11 @@ class ContentFile(File):
    A File-like object that takes just raw content, rather than an actual file.
    """
    def __init__(self, content, name=None):
        content = content or b''
        if six.PY3:
            stream_class = StringIO if isinstance(content, six.text_type) else BytesIO
        else:
            stream_class = BytesIO
            content = force_bytes(content)
        super(ContentFile, self).__init__(stream_class(content), name=name)
        self.size = len(content)

+19 −1
Original line number Diff line number Diff line
@@ -560,6 +560,13 @@ class InconsistentGetImageDimensionsBug(unittest.TestCase):

class ContentFileTestCase(unittest.TestCase):

    def setUp(self):
        self.storage_dir = tempfile.mkdtemp()
        self.storage = FileSystemStorage(self.storage_dir)

    def tearDown(self):
        shutil.rmtree(self.storage_dir)

    def test_content_file_default_name(self):
        self.assertEqual(ContentFile(b"content").name, None)

@@ -576,7 +583,18 @@ class ContentFileTestCase(unittest.TestCase):
        retrieved content is of the same type.
        """
        self.assertTrue(isinstance(ContentFile(b"content").read(), bytes))
        if six.PY3:
            self.assertTrue(isinstance(ContentFile("español").read(), six.text_type))
        else:
            self.assertTrue(isinstance(ContentFile("español").read(), bytes))

    def test_content_saving(self):
        """
        Test that ContentFile can be saved correctly with the filesystem storage,
        both if it was initialized with string or unicode content"""
        self.storage.save('bytes.txt', ContentFile(b"content"))
        self.storage.save('unicode.txt', ContentFile("español"))


class NoNameFileTestCase(unittest.TestCase):
    """