Browse Source

Fixed #27854 -- Added system check for nonexistent directories in STATICFILES_DIRS setting.

Jacob Walls 4 years ago
parent
commit
b23232b6ab

+ 12 - 4
django/contrib/staticfiles/finders.py

@@ -4,7 +4,7 @@ import os
 from django.apps import apps
 from django.conf import settings
 from django.contrib.staticfiles import utils
-from django.core.checks import Error
+from django.core.checks import Error, Warning
 from django.core.exceptions import ImproperlyConfigured
 from django.core.files.storage import (
     FileSystemStorage, Storage, default_storage,
@@ -91,6 +91,12 @@ class FileSystemFinder(BaseFinder):
                     'STATIC_ROOT setting.',
                     id='staticfiles.E002',
                 ))
+            if not os.path.isdir(root):
+                errors.append(Warning(
+                    f"The directory '{root}' in the STATICFILES_DIRS setting "
+                    f"does not exist.",
+                    id='staticfiles.W004',
+                ))
         return errors
 
     def find(self, path, all=False):
@@ -127,9 +133,11 @@ class FileSystemFinder(BaseFinder):
         List all files in all locations.
         """
         for prefix, root in self.locations:
-            storage = self.storages[root]
-            for path in utils.get_files(storage, ignore_patterns):
-                yield path, storage
+            # Skip nonexistent directories.
+            if os.path.isdir(root):
+                storage = self.storages[root]
+                for path in utils.get_files(storage, ignore_patterns):
+                    yield path, storage
 
 
 class AppDirectoriesFinder(BaseFinder):

+ 2 - 0
docs/ref/checks.txt

@@ -869,3 +869,5 @@ configured:
   contain the :setting:`STATIC_ROOT` setting.
 * **staticfiles.E003**: The prefix ``<prefix>`` in the
   :setting:`STATICFILES_DIRS` setting must not end with a slash.
+* **staticfiles.W004**: The directory ``<directory>`` in the
+  :setting:`STATICFILES_DIRS` does not exist.

+ 23 - 2
tests/staticfiles_tests/test_checks.py

@@ -3,8 +3,8 @@ from unittest import mock
 
 from django.conf import settings
 from django.contrib.staticfiles.checks import check_finders
-from django.contrib.staticfiles.finders import BaseFinder
-from django.core.checks import Error
+from django.contrib.staticfiles.finders import BaseFinder, get_finder
+from django.core.checks import Error, Warning
 from django.test import override_settings
 
 from .cases import CollectionTestCase
@@ -91,3 +91,24 @@ class FindersCheckTests(CollectionTestCase):
                     id='staticfiles.E003',
                 ),
             ])
+
+    def test_nonexistent_directories(self):
+        with self.settings(STATICFILES_DIRS=[
+            '/fake/path',
+            ('prefix', '/fake/prefixed/path'),
+        ]):
+            self.assertEqual(check_finders(None), [
+                Warning(
+                    "The directory '/fake/path' in the STATICFILES_DIRS "
+                    "setting does not exist.",
+                    id='staticfiles.W004',
+                ),
+                Warning(
+                    "The directory '/fake/prefixed/path' in the "
+                    "STATICFILES_DIRS setting does not exist.",
+                    id='staticfiles.W004',
+                ),
+            ])
+            # Nonexistent directories are skipped.
+            finder = get_finder('django.contrib.staticfiles.finders.FileSystemFinder')
+            self.assertEqual(list(finder.list(None)), [])