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

This commit is contained in:
Jacob Walls 2021-02-26 07:23:26 -05:00 committed by Mariusz Felisiak
parent 7186c536c4
commit b23232b6ab
3 changed files with 37 additions and 6 deletions

View File

@ -4,7 +4,7 @@ import os
from django.apps import apps from django.apps import apps
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles import utils 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.exceptions import ImproperlyConfigured
from django.core.files.storage import ( from django.core.files.storage import (
FileSystemStorage, Storage, default_storage, FileSystemStorage, Storage, default_storage,
@ -91,6 +91,12 @@ class FileSystemFinder(BaseFinder):
'STATIC_ROOT setting.', 'STATIC_ROOT setting.',
id='staticfiles.E002', 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 return errors
def find(self, path, all=False): def find(self, path, all=False):
@ -127,9 +133,11 @@ class FileSystemFinder(BaseFinder):
List all files in all locations. List all files in all locations.
""" """
for prefix, root in self.locations: for prefix, root in self.locations:
storage = self.storages[root] # Skip nonexistent directories.
for path in utils.get_files(storage, ignore_patterns): if os.path.isdir(root):
yield path, storage storage = self.storages[root]
for path in utils.get_files(storage, ignore_patterns):
yield path, storage
class AppDirectoriesFinder(BaseFinder): class AppDirectoriesFinder(BaseFinder):

View File

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

View File

@ -3,8 +3,8 @@ from unittest import mock
from django.conf import settings from django.conf import settings
from django.contrib.staticfiles.checks import check_finders from django.contrib.staticfiles.checks import check_finders
from django.contrib.staticfiles.finders import BaseFinder from django.contrib.staticfiles.finders import BaseFinder, get_finder
from django.core.checks import Error from django.core.checks import Error, Warning
from django.test import override_settings from django.test import override_settings
from .cases import CollectionTestCase from .cases import CollectionTestCase
@ -91,3 +91,24 @@ class FindersCheckTests(CollectionTestCase):
id='staticfiles.E003', 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)), [])