summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/staticfiles/management/commands/collectstatic.py14
-rw-r--r--docs/releases/1.9.5.txt3
-rw-r--r--tests/staticfiles_tests/storage.py37
-rw-r--r--tests/staticfiles_tests/test_management.py5
4 files changed, 54 insertions, 5 deletions
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index e6b6198952..793c211f42 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -218,12 +218,16 @@ class Command(BaseCommand):
smart_text(fpath), level=1)
else:
self.log("Deleting '%s'" % smart_text(fpath), level=1)
- full_path = self.storage.path(fpath)
- if not os.path.exists(full_path) and os.path.lexists(full_path):
- # Delete broken symlinks
- os.unlink(full_path)
- else:
+ try:
+ full_path = self.storage.path(fpath)
+ except NotImplementedError:
self.storage.delete(fpath)
+ else:
+ if not os.path.exists(full_path) and os.path.lexists(full_path):
+ # Delete broken symlinks
+ os.unlink(full_path)
+ else:
+ self.storage.delete(fpath)
for d in dirs:
self.clear_dir(os.path.join(path, d))
diff --git a/docs/releases/1.9.5.txt b/docs/releases/1.9.5.txt
index d74a2d9abe..98dd1799a8 100644
--- a/docs/releases/1.9.5.txt
+++ b/docs/releases/1.9.5.txt
@@ -27,3 +27,6 @@ Bugfixes
earlier versions of Django.
* Fixed a memory leak in the cached template loader (:ticket:`26306`).
+
+* Fixed a regression that caused ``collectstatic --clear`` to fail if the
+ storage doesn't implement ``path()`` (:ticket:`26297`).
diff --git a/tests/staticfiles_tests/storage.py b/tests/staticfiles_tests/storage.py
index fe4811a495..925f4b7fed 100644
--- a/tests/staticfiles_tests/storage.py
+++ b/tests/staticfiles_tests/storage.py
@@ -1,5 +1,8 @@
+import errno
+import os
from datetime import datetime
+from django.conf import settings
from django.contrib.staticfiles.storage import CachedStaticFilesStorage
from django.core.files import storage
@@ -22,6 +25,40 @@ class DummyStorage(storage.Storage):
return datetime.date(1970, 1, 1)
+class PathNotImplementedStorage(storage.Storage):
+
+ def _save(self, name, content):
+ return 'dummy'
+
+ def _path(self, name):
+ return os.path.join(settings.STATIC_ROOT, name)
+
+ def exists(self, name):
+ return os.path.exists(self._path(name))
+
+ def listdir(self, path):
+ path = self._path(path)
+ directories, files = [], []
+ for entry in os.listdir(path):
+ if os.path.isdir(os.path.join(path, entry)):
+ directories.append(entry)
+ else:
+ files.append(entry)
+ return directories, files
+
+ def delete(self, name):
+ name = self._path(name)
+ if os.path.exists(name):
+ try:
+ os.remove(name)
+ except OSError as e:
+ if e.errno != errno.ENOENT:
+ raise
+
+ def path(self, name):
+ raise NotImplementedError
+
+
class SimpleCachedStaticFilesStorage(CachedStaticFilesStorage):
def file_hash(self, name, content=None):
diff --git a/tests/staticfiles_tests/test_management.py b/tests/staticfiles_tests/test_management.py
index 94166f9888..b6c2a9fe87 100644
--- a/tests/staticfiles_tests/test_management.py
+++ b/tests/staticfiles_tests/test_management.py
@@ -166,6 +166,11 @@ class TestCollectionClear(CollectionTestCase):
shutil.rmtree(six.text_type(settings.STATIC_ROOT))
super(TestCollectionClear, self).run_collectstatic(clear=True)
+ @override_settings(STATICFILES_STORAGE='staticfiles_tests.storage.PathNotImplementedStorage')
+ def test_handle_path_notimplemented(self):
+ self.run_collectstatic()
+ self.assertFileNotFound('cleared.txt')
+
class TestCollectionExcludeNoDefaultIgnore(CollectionTestCase, TestDefaults):
"""