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

[1.6.x] 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.

Backport of 7e27885c from master.
parent 76700c54
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ 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.datastructures import SortedDict
from django.utils.functional import LazyObject
from django.utils.six.moves import input

from django.contrib.staticfiles import finders, storage
@@ -149,8 +150,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:
@@ -197,6 +197,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
@@ -22,6 +22,9 @@ from django.utils import six

from django.contrib.staticfiles import finders, storage

from .storage import DummyStorage


TEST_ROOT = os.path.dirname(upath(__file__))
TEST_SETTINGS = {
    'DEBUG': True,
@@ -233,6 +236,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):
    """