Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #19879 -- Have 'findstatic' says on which directories it search…

…ed the relative paths.

Added searched_locations in finders module. Added verbosity flag level 2 on 'findstatic'
command that will output the directories on which it searched the relative paths.

Reported by ccurvey. Initial patch by Jonas Svensson and Vajrasky Kok.
  • Loading branch information...
commit 6a9ed7d403a5f90a7c7354097aae99b74e8ce215 1 parent 935e6c1
@vajrasky vajrasky authored jezdez committed
View
12 django/contrib/staticfiles/finders.py
@@ -12,11 +12,15 @@
from django.contrib.staticfiles import utils
+# To keep track on which directories the finder has searched the static files.
+searched_locations = []
+
class BaseFinder(object):
"""
A base file finder to be used for custom staticfiles finder classes.
"""
+
def find(self, path, all=False):
"""
Given a relative file path this ought to find an
@@ -75,6 +79,8 @@ def find(self, path, all=False):
"""
matches = []
for prefix, root in self.locations:
+ if root not in searched_locations:
+ searched_locations.append(root)
matched_path = self.find_location(root, path, prefix)
if matched_path:
if not all:
@@ -147,6 +153,9 @@ def find(self, path, all=False):
"""
matches = []
for app in self.apps:
+ app_location = self.storages[app].location
+ if app_location not in searched_locations:
+ searched_locations.append(app_location)
match = self.find_in_app(app, path)
if match:
if not all:
@@ -195,6 +204,8 @@ def find(self, path, all=False):
except NotImplementedError:
pass
else:
+ if self.storage.location not in searched_locations:
+ searched_locations.append(self.storage.location)
if self.storage.exists(path):
match = self.storage.path(path)
if all:
@@ -232,6 +243,7 @@ def find(path, all=False):
If ``all`` is ``False`` (default), return the first matching
absolute path (or ``None`` if no match). Otherwise return a list.
"""
+ searched_locations[:] = []
matches = []
for finder in get_finders():
result = finder.find(path, all=all)
View
16 django/contrib/staticfiles/management/commands/findstatic.py
@@ -21,15 +21,25 @@ def handle_label(self, path, **options):
verbosity = int(options.get('verbosity', 1))
result = finders.find(path, all=options['all'])
path = force_text(path)
+ if verbosity >= 2:
+ searched_locations = ("Looking in the following locations:\n %s" %
+ "\n ".join(force_text(location)
+ for location in finders.searched_locations))
+ else:
+ searched_locations = ''
if result:
if not isinstance(result, (list, tuple)):
result = [result]
result = (force_text(os.path.realpath(path)) for path in result)
if verbosity >= 1:
- output = '\n '.join(result)
- return "Found '%s' here:\n %s" % (path, output)
+ file_list = '\n '.join(result)
+ return ("Found '%s' here:\n %s\n%s" %
+ (path, file_list, searched_locations))
else:
return '\n'.join(result)
else:
+ message = ["No matching file found for '%s'." % path]
+ if verbosity >= 2:
+ message.append(searched_locations)
if verbosity >= 1:
- self.stderr.write("No matching file found for '%s'." % path)
+ self.stderr.write('\n'.join(message))
View
34 docs/ref/contrib/staticfiles.txt
@@ -162,6 +162,23 @@ output and just get the path names::
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
+On the other hand, by setting the :djadminopt:`--verbosity` flag to 2, you can
+get all the directories on which it searched the relative paths::
+
+ $ python manage.py findstatic css/base.css --verbosity 2
+ Found 'css/base.css' here:
+ /home/special.polls.com/core/static/css/base.css
+ /home/polls.com/core/static/css/base.css
+ Looking in the following locations:
+ /home/special.polls.com/core/static
+ /home/polls.com/core/static
+ /some/other/path/static
+
+.. versionadded:: 1.7
+
+ The additional message of on which directories it searched the relative
+ paths is new in Django 1.7.
+
.. _staticfiles-runserver:
runserver
@@ -366,6 +383,23 @@ files:
.. _staticfiles-development-view:
+Finders Module
+==============
+
+``staticfiles`` finders has a ``searched_locations`` list with directory paths
+in which they search for the relative paths. Example usage::
+
+ from django.contrib.staticfiles import finders
+
+ result = finders.find('css/base.css')
+ searched_locations = finders.searched_locations
+
+.. versionadded:: 1.7
+
+The ``get_searched_locations`` function is new in Django 1.7. Previously, we
+have to check the locations of our :setting:`STATICFILES_FINDERS` manually
+one by one.
+
Static file development view
----------------------------
View
4 docs/releases/1.7.txt
@@ -1051,6 +1051,10 @@ Miscellaneous
which does allow primary keys with value 0. It only forbids *autoincrement*
primary keys with value 0.
+* :djadmin:`findstatic` now accepts verbosity flag level 2, meaning it will
+ show the directories on which it searched the relative paths. See
+ :djadmin:`findstatic` for example output.
+
.. _deprecated-features-1.7:
Features deprecated in 1.7
View
37 tests/staticfiles_tests/tests.py
@@ -223,6 +223,35 @@ def test_all_files_less_verbose(self):
self.assertIn('project', force_text(lines[0]))
self.assertIn('apps', force_text(lines[1]))
+ def test_all_files_more_verbose(self):
+ """
+ Test that findstatic returns all candidate files if run without --first and -v2.
+ Also, test that findstatic returns the searched locations with -v2.
+ """
+ out = six.StringIO()
+ call_command('findstatic', 'test/file.txt', verbosity=2, stdout=out)
+ out.seek(0)
+ lines = [l.strip() for l in out.readlines()]
+ self.assertIn('project', force_text(lines[1]))
+ self.assertIn('apps', force_text(lines[2]))
+ self.assertIn("Looking in the following locations:", force_text(lines[3]))
+ searched_locations = ', '.join(lines[4:])
+ #AppDirectoriesFinder searched locations
+ self.assertIn(os.path.join('staticfiles_tests', 'apps', 'test', 'static'),
+ searched_locations)
+ self.assertIn(os.path.join('staticfiles_tests', 'apps', 'no_label', 'static'),
+ searched_locations)
+ self.assertIn(os.path.join('django', 'contrib', 'admin', 'static'),
+ searched_locations)
+ self.assertIn(os.path.join('django', 'tests', 'servers', 'another_app', 'static'),
+ searched_locations)
+ #FileSystemFinder searched locations
+ self.assertIn(TEST_SETTINGS['STATICFILES_DIRS'][1][1], searched_locations)
+ self.assertIn(TEST_SETTINGS['STATICFILES_DIRS'][0], searched_locations)
+ #DefaultStorageFinder searched locations
+ self.assertIn(os.path.join('staticfiles_tests', 'project', 'site_media', 'media'),
+ searched_locations)
+
class TestConfiguration(StaticFilesTestCase):
def test_location_empty(self):
@@ -779,6 +808,9 @@ def setUp(self):
self.find_all = ('media-file.txt', [test_file_path])
+@override_settings(STATICFILES_FINDERS=
+ ('django.contrib.staticfiles.finders.FileSystemFinder',),
+ STATICFILES_DIRS=[os.path.join(TEST_ROOT, 'project', 'documents')])
class TestMiscFinder(TestCase):
"""
A few misc finder tests.
@@ -805,6 +837,11 @@ def test_cache(self):
self.assertEqual(cache_info.hits, 9)
self.assertEqual(cache_info.currsize, 1)
+ def test_searched_locations(self):
+ finders.find('spam')
+ self.assertEqual(finders.searched_locations,
+ [os.path.join(TEST_ROOT, 'project', 'documents')])
+
@override_settings(STATICFILES_DIRS='a string')
def test_non_tuple_raises_exception(self):
"""
Please sign in to comment.
Something went wrong with that request. Please try again.