[1.6.x] Reworked the detection of local storages for the collectstatic command.

Before 4befb30 the detection was broken because we used isinstance
against a LazyObject rather than against a Storage class. That commit
fixed it by looking directly at the object wrapped by LazyObject.
This could however be a problem to anyone who subclasses the
collectstatic management Command and directly supplies a Storage class.

Refs #21581.

Backport of 7e27885c6e from master.
This commit is contained in:
Loic Bistuer 2014-02-12 22:07:23 +07:00 committed by Tim Graham
parent 76700c5437
commit d6db48e5f6
2 changed files with 35 additions and 2 deletions

View File

@ -8,6 +8,7 @@ from django.core.files.storage import FileSystemStorage
from django.core.management.base import CommandError, NoArgsCommand from django.core.management.base import CommandError, NoArgsCommand
from django.utils.encoding import smart_text from django.utils.encoding import smart_text
from django.utils.datastructures import SortedDict from django.utils.datastructures import SortedDict
from django.utils.functional import LazyObject
from django.utils.six.moves import input from django.utils.six.moves import input
from django.contrib.staticfiles import finders, storage from django.contrib.staticfiles import finders, storage
@ -149,8 +150,7 @@ class Command(NoArgsCommand):
'location as specified in your settings' 'location as specified in your settings'
) )
if (isinstance(self.storage._wrapped, FileSystemStorage) and if self.is_local_storage() and self.storage.location:
self.storage.location):
destination_path = self.storage.location destination_path = self.storage.location
message.append(':\n\n %s\n\n' % destination_path) message.append(':\n\n %s\n\n' % destination_path)
else: else:
@ -197,6 +197,13 @@ class Command(NoArgsCommand):
if self.verbosity >= level: if self.verbosity >= level:
self.stdout.write(msg) self.stdout.write(msg)
def is_local_storage(self):
if issubclass(self.storage.__class__, LazyObject):
storage = self.storage._wrapped
else:
storage = self.storage
return isinstance(storage, FileSystemStorage)
def clear_dir(self, path): def clear_dir(self, path):
""" """
Deletes the given relative path using the destination storage backend. Deletes the given relative path using the destination storage backend.

View File

@ -22,6 +22,9 @@ from django.utils import six
from django.contrib.staticfiles import finders, storage from django.contrib.staticfiles import finders, storage
from .storage import DummyStorage
TEST_ROOT = os.path.dirname(upath(__file__)) TEST_ROOT = os.path.dirname(upath(__file__))
TEST_SETTINGS = { TEST_SETTINGS = {
'DEBUG': True, 'DEBUG': True,
@ -233,6 +236,29 @@ class TestConfiguration(StaticFilesTestCase):
'without having set the STATIC_ROOT setting to a filesystem path'): 'without having set the STATIC_ROOT setting to a filesystem path'):
call_command('collectstatic', interactive=False, verbosity=0, stderr=err) call_command('collectstatic', interactive=False, verbosity=0, stderr=err)
def test_local_storage_detection_helper(self):
staticfiles_storage = storage.staticfiles_storage
try:
storage.staticfiles_storage._wrapped = empty
with override_settings(STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage'):
command = collectstatic.Command()
self.assertTrue(command.is_local_storage())
storage.staticfiles_storage._wrapped = empty
with override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.DummyStorage'):
command = collectstatic.Command()
self.assertFalse(command.is_local_storage())
storage.staticfiles_storage = storage.FileSystemStorage()
command = collectstatic.Command()
self.assertTrue(command.is_local_storage())
storage.staticfiles_storage = DummyStorage()
command = collectstatic.Command()
self.assertFalse(command.is_local_storage())
finally:
storage.staticfiles_storage = staticfiles_storage
class TestCollection(CollectionTestCase, TestDefaults): class TestCollection(CollectionTestCase, TestDefaults):
""" """