在部署到 Heroku 的 Django 1.11 应用程序上。当加载根 URL
/
时(我推测当 Django 到达 {% static 'angular/angular.min.js' %}
模板中的 homepage.html
时),我收到以下错误:
ValueError: Missing staticfiles manifest entry for 'angular/angular.min.js'
File "django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "homepage/views.py", line 87, in homepage
"latest_python3": Version.objects.filter(supports_python3=True).select_related("package").distinct().order_by("-created")[0:5]
File "django/shortcuts.py", line 30, in render
content = loader.render_to_string(template_name, context, request, using=using)
File "django/template/loader.py", line 68, in render_to_string
return template.render(context, request)
File "django/template/backends/django.py", line 66, in render
return self.template.render(context)
File "django/template/base.py", line 207, in render
return self._render(context)
File "newrelic/api/function_trace.py", line 60, in dynamic_wrapper
return wrapped(*args, **kwargs)
File "django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "django/template/base.py", line 957, in render_annotated
return self.render(context)
File "django/template/loader_tags.py", line 177, in render
return compiled_parent._render(context)
File "newrelic/api/function_trace.py", line 60, in dynamic_wrapper
return wrapped(*args, **kwargs)
File "django/template/base.py", line 199, in _render
return self.nodelist.render(context)
File "django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "django/template/base.py", line 957, in render_annotated
return self.render(context)
File "django/template/defaulttags.py", line 411, in render
return strip_spaces_between_tags(self.nodelist.render(context).strip())
File "django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "django/template/base.py", line 957, in render_annotated
return self.render(context)
File "newrelic/hooks/framework_django.py", line 765, in wrapper
return wrapped(*args, **kwargs)
File "django/template/loader_tags.py", line 72, in render
result = block.nodelist.render(context)
File "django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "django/template/base.py", line 957, in render_annotated
return self.render(context)
File "django/templatetags/static.py", line 105, in render
url = self.url(context)
File "django/templatetags/static.py", line 102, in url
return self.handle_simple(path)
File "django/templatetags/static.py", line 117, in handle_simple
return staticfiles_storage.url(path)
File "django/contrib/staticfiles/storage.py", line 162, in url
return self._url(self.stored_name, name, force)
File "django/contrib/staticfiles/storage.py", line 141, in _url
hashed_name = hashed_name_func(*args)
File "django/contrib/staticfiles/storage.py", line 432, in stored_name
raise ValueError("Missing staticfiles manifest entry for '%s'" % clean_name)
我对 Django 文档的理解是,清单是一个名为 staticfiles.json
的文件。该文件似乎包含正确的条目(出于格式原因,我删除了所有不相关的条目):
$ heroku run cat ./staticfiles/staticfiles.json
Running cat ./staticfiles/staticfiles.json
{"paths": {"angular/angular.min.js": "angular/angular.min.df1c56732ca5.js", "angular/controllers.js": "angular/controllers.af8e9f9a2645.js"}, "version": "1.0"}
相关设置:
Heroku 的说明使用 Django 服务静态文件:
# in requirements.txt
whitenoise
# in settings/base.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static"),]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
# ...others here too
]
django_heroku.settings(locals())
(更新:STATICFILES_STORAGE)
STATICFILES_STORAGE
的值设置为
whitenoise.storage.CompressedManifestStaticFilesStorage
。我通过在 settings.py 文件末尾添加
del STATICFILES_STORAGE
来删除它。然后 Django 将值重置为默认值
django.contrib.staticfiles.storage.StaticFilesStorage
。结果是所有静态文件在浏览器中要么出现 404 错误,要么出现 MIME 类型错误。
删除开头的斜线。
改变:
{% static '/admin/js/vendor/jquery/jquery.js' %}
{% static 'admin/js/vendor/jquery/jquery.js' %}
解决了我的问题。
更新: 此问题现已修复。遗憾的是,该解决方案对其他人没有用。对此表示歉意。问题是我的设置被导入的另一个模块中的设置覆盖。我在上面的问题中列出的设置实际上在 Heroku 上有效。对不起大家,也感谢那些帮助我调试这个问题的人。
ValueError
是由Django静态文件应用程序引发的,但是 - 在你的情况下 - 它实际上来自WhiteNoise,准确地说是来自
whitenoise.storage.CompressedManifestStaticFilesStorage
。该主题在 Django 上的 WhiteNoise 文档的“附加注释”部分中进行了讨论。
仅供参考,例如,当我在 Django Restframework 端点上使用 Pytest 运行测试时(使用 format=api
请求上下文),我会遇到相同的错误。
WhiteNoise 文档建议使用 findstatic
分析问题,如果没有其他方法有助于通过 Django 项目设置中的
WHITENOISE_MANIFEST_STRICT = False
消除错误。这可能归结为在任何事情之前(甚至在运行测试之前)运行
collectstatic
,例如
python manage.py collectstatic --noinput
P.S.:您不应该将del STATICFILES_STORAGE
添加到设置模块的末尾。这将违背使用 WhiteNoise 进行静态文件优化的目的。