diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index a4737175ac..347bd6bc36 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -118,8 +118,18 @@ class AbstractImage(models.Model, TagSearchable): # Open file if it is closed close_file = False try: + image_file = self.file + if self.file.closed: - self.file.open('rb') + # Reopen the file + if self.is_stored_locally(): + self.file.open('rb') + else: + # Some external storage backends don't allow reopening + # the file. Get a fresh file instance. #1397 + storage = self._meta.get_field('file').storage + image_file = storage.open(self.file.name, 'rb') + close_file = True except IOError as e: # re-throw this as a SourceImageIOError so that calling code can distinguish @@ -127,13 +137,13 @@ class AbstractImage(models.Model, TagSearchable): raise SourceImageIOError(text_type(e)) # Seek to beginning - self.file.seek(0) + image_file.seek(0) try: - yield WillowImage.open(self.file) + yield WillowImage.open(image_file) finally: if close_file: - self.file.close() + image_file.close() def get_rect(self): return Rect(0, 0, self.width, self.height) diff --git a/wagtail/wagtailimages/tests/test_admin_views.py b/wagtail/wagtailimages/tests/test_admin_views.py index 5205bee228..593d44c530 100644 --- a/wagtail/wagtailimages/tests/test_admin_views.py +++ b/wagtail/wagtailimages/tests/test_admin_views.py @@ -1,7 +1,6 @@ from __future__ import unicode_literals import json -import unittest from django.test import TestCase, override_settings from django.utils.http import urlquote @@ -156,7 +155,6 @@ class TestImageEditView(TestCase, WagtailTestUtils): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailimages/images/edit.html') - @unittest.expectedFailure @override_settings(DEFAULT_FILE_STORAGE='wagtail.tests.dummy_external_storage.DummyExternalStorage') def test_simple_with_external_storage(self): # The view calls get_file_size on the image that closes the file if @@ -352,7 +350,6 @@ class TestImageChooserUploadView(TestCase, WagtailTestUtils): # The form should have an error self.assertFormError(response, 'uploadform', 'file', "This field is required.") - @unittest.expectedFailure @override_settings(DEFAULT_FILE_STORAGE='wagtail.tests.dummy_external_storage.DummyExternalStorage') def test_upload_with_external_storage(self): response = self.client.post(reverse('wagtailimages:chooser_upload'), {