Commit 7e27885c authored by Loic Bistuer's avatar Loic Bistuer Committed by Tim Graham
Browse files

Reworked the detection of local storages for the collectstatic command.

Before 4befb301 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.
parent 73f51e41
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ from optparse import make_option
from django.core.files.storage import FileSystemStorage
from django.core.management.base import CommandError, NoArgsCommand
from django.utils.encoding import smart_text
from django.utils.functional import LazyObject
from django.utils.six.moves import input

from django.contrib.staticfiles import finders, storage
@@ -144,8 +145,7 @@ class Command(NoArgsCommand):
            'location as specified in your settings'
        )

        if (isinstance(self.storage._wrapped, FileSystemStorage) and
                self.storage.location):
        if self.is_local_storage() and self.storage.location:
            destination_path = self.storage.location
            message.append(':\n\n    %s\n\n' % destination_path)
        else:
@@ -192,6 +192,13 @@ class Command(NoArgsCommand):
        if self.verbosity >= level:
            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):
        """
        Deletes the given relative path using the destination storage backend.
+26 −0
Original line number Diff line number Diff line
@@ -23,6 +23,9 @@ from django.utils import six
from django.contrib.staticfiles import finders, storage
from django.contrib.staticfiles.management.commands import collectstatic

from .storage import DummyStorage


TEST_ROOT = os.path.dirname(upath(__file__))
TEST_SETTINGS = {
    'DEBUG': True,
@@ -263,6 +266,29 @@ class TestConfiguration(StaticFilesTestCase):
                        'without having set the STATIC_ROOT setting to a filesystem path'):
                    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):
    """