diff --git a/django/contrib/staticfiles/finders.py b/django/contrib/staticfiles/finders.py index 45bf4a1023..7b4c7c8178 100644 --- a/django/contrib/staticfiles/finders.py +++ b/django/contrib/staticfiles/finders.py @@ -3,7 +3,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import default_storage, Storage, FileSystemStorage from django.utils.datastructures import SortedDict -from django.utils.functional import memoize, LazyObject +from django.utils.functional import empty, memoize, LazyObject from django.utils.importlib import import_module from django.utils._os import safe_join @@ -133,7 +133,7 @@ class AppDirectoriesFinder(BaseFinder): List all files in all app storages. """ for storage in self.storages.itervalues(): - if storage.exists(''): # check if storage location exists + if storage.exists(''): # check if storage location exists for path in utils.get_files(storage, ignore_patterns): yield path, storage @@ -210,12 +210,21 @@ class BaseStorageFinder(BaseFinder): for path in utils.get_files(self.storage, ignore_patterns): yield path, self.storage + class DefaultStorageFinder(BaseStorageFinder): """ A static files finder that uses the default storage backend. """ storage = default_storage + def __init__(self, *args, **kwargs): + super(DefaultStorageFinder, self).__init__(*args, **kwargs) + base_location = getattr(self.storage, 'base_location', empty) + if not base_location: + raise ImproperlyConfigured("The storage backend of the " + "staticfiles finder %r doesn't have " + "a valid location." % self.__class__) + def find(path, all=False): """ @@ -237,10 +246,12 @@ def find(path, all=False): # No match. return all and [] or None + def get_finders(): for finder_path in settings.STATICFILES_FINDERS: yield get_finder(finder_path) + def _get_finder(import_path): """ Imports the staticfiles finder class described by import_path, where diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 73126a3cb9..aa62175819 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -12,7 +12,8 @@ from django.utils.encoding import force_unicode, filepath_to_uri from django.utils.functional import LazyObject from django.utils.importlib import import_module from django.utils.text import get_valid_filename -from django.utils._os import safe_join +from django.utils._os import safe_join, abspathu + __all__ = ('Storage', 'FileSystemStorage', 'DefaultStorage', 'default_storage') @@ -145,9 +146,10 @@ class FileSystemStorage(Storage): def __init__(self, location=None, base_url=None): if location is None: location = settings.MEDIA_ROOT + self.base_location = location + self.location = abspathu(self.base_location) if base_url is None: base_url = settings.MEDIA_URL - self.location = os.path.abspath(location) self.base_url = base_url def _open(self, name, mode='rb'): diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py index f00d502931..6a7a46af21 100644 --- a/tests/regressiontests/file_storage/tests.py +++ b/tests/regressiontests/file_storage/tests.py @@ -96,6 +96,14 @@ class FileStorageTests(unittest.TestCase): shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir2) + def test_emtpy_location(self): + """ + Makes sure an exception is raised if the location is empty + """ + storage = self.storage_class(location='') + self.assertEqual(storage.base_location, '') + self.assertEqual(storage.location, os.getcwd()) + def test_file_access_options(self): """ Standard file access options are available, and work as expected. diff --git a/tests/regressiontests/staticfiles_tests/tests.py b/tests/regressiontests/staticfiles_tests/tests.py index 8a179141b9..5c141f695a 100644 --- a/tests/regressiontests/staticfiles_tests/tests.py +++ b/tests/regressiontests/staticfiles_tests/tests.py @@ -496,6 +496,9 @@ class TestMiscFinder(TestCase): """ A few misc finder tests. """ + def setUp(self): + default_storage._wrapped = empty + def test_get_finder(self): self.assertTrue(isinstance(finders.get_finder( 'django.contrib.staticfiles.finders.FileSystemFinder'), @@ -509,13 +512,17 @@ class TestMiscFinder(TestCase): self.assertRaises(ImproperlyConfigured, finders.get_finder, 'foo.bar.FooBarFinder') + @override_settings(STATICFILES_DIRS='a string') def test_non_tuple_raises_exception(self): """ We can't determine if STATICFILES_DIRS is set correctly just by looking at the type, but we can determine if it's definitely wrong. """ - with self.settings(STATICFILES_DIRS='a string'): - self.assertRaises(ImproperlyConfigured, finders.FileSystemFinder) + self.assertRaises(ImproperlyConfigured, finders.FileSystemFinder) + + @override_settings(MEDIA_ROOT='') + def test_location_empty(self): + self.assertRaises(ImproperlyConfigured, finders.DefaultStorageFinder) class TestTemplateTag(StaticFilesTestCase):