#31520: ManifestStaticFilesStorage should not raise ValueError on missing file
when
manifest_strict=False
-----------------------------------------+------------------------
Reporter: thenewguy | Owner: nobody
Type: Uncategorized | Status: new
Component: Uncategorized | Version: 3.0
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-----------------------------------------+------------------------
I am using ManifestStaticFilesStorage and was under the impression that
subclassing and setting `manifest_strict=False` would allow pages to
render if a static file is missing (perhaps due to a template typo)
instead of raising a ValueError.
However, if the file is missing from disk a ValueError is raised.
I believe this is an oversight as it would be preferrable for a typo to
cause a 404 instead of preventing a page from rendering.
Adding this try/except block lets the page render and the tests below
pass. Otherwise they fail when the files do not exist.
{{{
if cache_name is None:
if self.manifest_strict:
raise ValueError("Missing staticfiles manifest entry for
'%s'" % clean_name)
try:
hashed = self.hashed_name(name)
except ValueError:
hashed = name
cache_name = self.clean_name(hashed)
}}}
This is what the reworked function looks like:
{{{
def stored_name(self, name):
parsed_name = urlsplit(unquote(name))
clean_name = parsed_name.path.strip()
hash_key = self.hash_key(clean_name)
cache_name = self.hashed_files.get(hash_key)
if cache_name is None:
if self.manifest_strict:
raise ValueError("Missing staticfiles manifest entry for
'%s'" % clean_name)
try:
hashed = self.hashed_name(name)
except ValueError:
hashed = name
cache_name = self.clean_name(hashed)
unparsed_name = list(parsed_name)
unparsed_name[2] = cache_name
# Special casing for a @font-face hack, like
url(myfont.eot?#iefix")
# http://www.fontspring.com/blog/the-new-bulletproof-font-face-
syntax
if '?#' in name and not unparsed_name[3]:
unparsed_name[2] += '?'
return urlunsplit(unparsed_name)
}}}
And here are the tests:
{{{
from os.path import exists
from django.conf import settings
from django.templatetags.static import static
from django.test import SimpleTestCase, override_settings
@override_settings(STATIC_URL='/static/')
class StaticResolveTest(SimpleTestCase):
def test_existing_static_path_resolves(self):
location = 'admin/js/vendor/jquery/jquery.js'
path = join(settings.STATIC_ROOT, location)
self.assertTrue(exists(path), 'Path "%s" did not exist' % path)
static_location = static(location)
static_location_parts = static_location.split('.')
self.assertEqual(static_location_parts[0],
'/static/admin/js/vendor/jquery/jquery')
self.assertEqual(static_location_parts[-1], 'js')
def test_missing_static_path_resolves(self):
location = 'does-not-exist.txt'
path = join(settings.STATIC_ROOT, location)
self.assertFalse(exists(path), 'Path "%s" was not supposed to
exist' % path)
self.assertEqual(static(location), '/static/does-not-exist.txt')
def test_served_static_response(self):
location = 'admin/js/vendor/jquery/jquery.js'
path = join(settings.STATIC_ROOT, location)
self.assertTrue(exists(path), 'Path "%s" did not exist' % path)
response = self.client.get(static(location))
self.assertEqual(response.status_code, 200)
self.assertTrue(response.streaming)
response_content = b''.join(response.streaming_content)
with open(path, 'rb') as fp:
disk_content = fp.read()
self.assertEqual(response_content, disk_content)
def test_missing_static_response(self):
location = 'does-not-exist.txt'
path = join(settings.STATIC_ROOT, location)
self.assertFalse(exists(path), 'Path "%s" was not supposed to
exist' % path)
response = self.client.get(static(location))
self.assertEqual(response.status_code, 404)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/31520>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/052.b178f73ff4426f6520796a881a321e6d%40djangoproject.com.