ValueError: Отсутствует запись манифеста staticfiles для 'favicon.ico'
Я запускаю ValueError
при запуске python manage.py test
. Мой проект называется fellow_go
, и я в настоящее время работаю над приложением под названием pickup
.
Обратите внимание, что эта ошибка добавлена в относительно недавнюю фиксацию для Django: Исправлено # 24452 - Исправлена проблема с hashedFilesMixin с вложенными путями..
======================================================================
ERROR: test_view_url_exists_at_desired_location (pickup.tests.test_view.HomePageViewTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/sunqingyao/PycharmProjects/fellow_go/pickup/tests/test_view.py", line 10, in test_view_url_exists_at_desired_location
resp = self.client.get('/', follow=True)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/client.py", line 536, in get
**extra)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/client.py", line 340, in get
return self.generic('GET', path, secure=secure, **r)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/client.py", line 416, in generic
return self.request(**r)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/client.py", line 501, in request
six.reraise(*exc_info)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/utils/six.py", line 686, in reraise
raise value
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/core/handlers/base.py", line 217, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/core/handlers/base.py", line 215, in _get_response
response = response.render()
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/response.py", line 107, in render
self.content = self.rendered_content
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/response.py", line 84, in rendered_content
content = template.render(context, self._request)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/backends/django.py", line 66, in render
return self.template.render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/base.py", line 207, in render
return self._render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/utils.py", line 107, in instrumented_test_render
return self.nodelist.render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
return self.render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/loader_tags.py", line 177, in render
return compiled_parent._render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/test/utils.py", line 107, in instrumented_test_render
return self.nodelist.render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/base.py", line 990, in render
bit = node.render_annotated(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/template/base.py", line 957, in render_annotated
return self.render(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/templatetags/static.py", line 105, in render
url = self.url(context)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/templatetags/static.py", line 102, in url
return self.handle_simple(path)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/templatetags/static.py", line 117, in handle_simple
return staticfiles_storage.url(path)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 162, in url
return self._url(self.stored_name, name, force)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 141, in _url
hashed_name = hashed_name_func(*args)
File "/Users/sunqingyao/Envs/django_tutorial/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 432, in stored_name
raise ValueError("Missing staticfiles manifest entry for '%s'" % clean_name)
ValueError: Missing staticfiles manifest entry for 'favicon.ico'
----------------------------------------------------------------------
fellow_go/settings.py
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
# ......
# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
fellow_go/urls.py
urlpatterns = i18n_patterns(
url(r'^$', HomePageView.as_view(), name='index'),
url(r'^pickup/', include('pickup.urls')),
url(r'^accounts/', include('django.contrib.auth.urls')),
url(r'^admin/', admin.site.urls),
prefix_default_language=False
) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
fellow_go/пикап/views.py
class HomePageView(TemplateView):
template_name = 'index.html'
fellow_go/шаблоны/index.html
<link rel="icon" href="{% static "favicon.ico" %}">
fellow_go/пикап/Тесты/test_view.py
class HomePageViewTest(TestCase):
def test_view_url_exists_at_desired_location(self):
resp = self.client.get('/', follow=True)
self.assertEqual(resp.status_code, 200)
У меня есть файл favicon.ico
:
![введите описание изображения здесь]()
Странно, с python manage.py runserver
ошибок не возникает:
/Users/sunqingyao/Envs/django_tutorial/bin/python3.6 /Users/sunqingyao/PycharmProjects/fellow_go/manage.py runserver 8000
Performing system checks...
System check identified no issues (0 silenced).
May 24, 2017 - 22:09:25
Django version 1.11.1, using settings 'fellow_go.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
[24/May/2017 22:09:28] "GET / HTTP/1.1" 200 6276
[24/May/2017 22:09:28] "GET /static/css/style.min.css HTTP/1.1" 200 2474
[24/May/2017 22:09:28] "GET /static/css/ie10-viewport-bug-workaround.css HTTP/1.1" 200 430
[24/May/2017 22:09:28] "GET /static/js/ie10-viewport-bug-workaround.js HTTP/1.1" 200 685
[24/May/2017 22:09:28] "GET /static/js/opt-in.js HTTP/1.1" 200 511
[24/May/2017 22:09:28] "GET /static/css/datetimepicker.css HTTP/1.1" 200 12351
[24/May/2017 22:09:28] "GET /static/js/bootstrap-datetimepicker.js HTTP/1.1" 200 55741
[24/May/2017 22:09:35] "GET /static/favicon.ico HTTP/1.1" 200 766
Not Found: /apple-touch-icon-precomposed.png
[24/May/2017 22:09:35] "GET /apple-touch-icon-precomposed.png HTTP/1.1" 404 2678
Not Found: /apple-touch-icon.png
[24/May/2017 22:09:35] "GET /apple-touch-icon.png HTTP/1.1" 404 2642
Скажите, пожалуйста, что случилось с моим кодом.
Ответы
Ответ 1
Попробуйте запустить:
python manage.py collectstatic
Работает ли тест? Если это так, это может привести к возникновению проблемы:
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
по теме:
fooobar.com/questions/311791/...
Ознакомьтесь с документацией Django:
https://docs.djangoproject.com/en/1.11/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage.manifest_strict
Ответ 2
Если вы хотите продолжать использовать модуль WhiteNoise в своем проекте Django 1.11 (или новее), одновременно предотвращая эту ошибку "Отсутствует запись манифеста статических файлов", вам необходимо отключить атрибут manifest_strict
посредством наследования, как отмечено в документации Django.
Как это сделать?
Во-первых, создайте файл storage.py
в каталоге вашего проекта:
from whitenoise.storage import CompressedManifestStaticFilesStorage
class WhiteNoiseStaticFilesStorage(CompressedManifestStaticFilesStorage):
manifest_strict = False
Во-вторых, отредактируйте константу STATICFILES_STORAGE
в файле settings.py
чтобы указать на этот новый класс, например:
STATICFILES_STORAGE = 'my_project.storage.WhiteNoiseStaticFilesStorage'
Ответ 3
Это не обязательно происходит с пакетом whitenoise
. Изменение STATIC_STORAGE
на django.contrib.staticfiles.storage.ManifestStaticFilesStorage
приведет к той же ошибке при выполнении тестов, начиная с Django 1.11.
Это происходит потому, что ManifestStaticFilesStorage
ожидает, что staticfiles.json
существует, а содержит запрашиваемый файл. Вы можете подтвердить это, запустив ./manage.py collectstatic
и повторив попытку.
Обычно вы не видите эту ошибку в разработке, потому что, когда DEBUG == True
, ManifestStaticFilesStorage
переключается на нехешированные URL.
Чтобы преодолеть это, вы должны убедиться, что:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.StaticFilesStorage'
По умолчанию.
Одним из способов было бы переопределить настройки для тестового класса:
from django.test import TestCase, override_settings
@override_settings(STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage')
class MyTest(TestCase):
pass
или метод:
from django.test import TestCase, override_settings
class MyTest(TestCase):
@override_settings(STATICFILES_STORAGE='django.contrib.staticfiles.storage.StaticFilesStorage')
def test_something(self):
pass
Ответ 4
Django вызывает это исключение, если вы ссылаетесь на статический файл во время тестов, но вы не запускали ./manage.py collectstatic
с момента создания этого файла (см. Эти документы).
Рекомендуемый способ решения этой проблемы:
Во время тестирования убедитесь, что для параметра STATICFILES_STORAGE установлено другое значение, например "django.contrib.staticfiles.storage.StaticFilesStorage" (по умолчанию).
Вот простой способ сделать это в вашем settings.py
:
import sys
TESTING = len(sys.argv) > 1 and sys.argv[1] == 'test'
STATICFILES_STORAGE = (
'django.contrib.staticfiles.storage.StaticFilesStorage'
if TESTING
else 'whitenoise.storage.CompressedManifestStaticFilesStorage'
)
Ответ 5
Просто поделюсь решением, которое у меня было с этим вопросом, на случай, если оно кому-нибудь поможет.
Я случайно включил ведущий "/" в некоторые статические URL, что привело к их отсутствию в манифесте.
Решение состояло в том, чтобы заменить все экземпляры:
{% static '/path/to/some/file' %}
с
{% static 'path/to/some/file' %}
и тогда все работало правильно.