Django staticfiles не найден на Heroku (с whitenoise)

Этот вопрос, кажется, задан несколько раз, но я не могу это исправить.

Я развернул приложение django для создания с DEBUG = False. Я установил allowed_host. Я использовал {% load static from staticfiles %} для загрузки статических файлов. Я точно пишу настройки, затребованные документом Heroku:

BASE_DIR = os.path.dirname(os.path.dirname(__file__))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))

STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
STATIC_URL = '/static/'

STATICFILES_DIRS = (
    os.path.join(PROJECT_ROOT, 'static'),
)

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

НО я получил ошибку 500. И получил эту трассировку (по почте)

...
`cache_name = self.clean_name(self.hashed_name(name))
 File "/app/.heroku/python/lib/python3.5/site-    packages/django/contrib/staticfiles/storage.py", line 94, in hashed_name (clean_name, self))
...
ValueError: The file ‘app/css/font.css’ could not be found with <whitenoise.django.GzipManifestStaticFilesStorage object at 0x7febf600a7f0>.`

Когда я запустил heroku run python manage.py collectstatic --noinput Все выглядит нормально:

276 static files copied to '/app/annuaire/staticfiles', 276 post-processed.

Есть ли у кого-нибудь идея помочь мне, пожалуйста?

Спасибо

ИЗМЕНИТЬ:

annuaire
|-- /annuaire
|-- -- /settings.py
|-- /app
|-- -- /static/...`

wsgi.py

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise


application = get_wsgi_application()
application = DjangoWhiteNoise(application)

Ответ 1

Я понял. Мне нужно было добавить python manage.py collectstatic --noinput; в моем Procfile. Heroku док сказал, что collecticstatic автоматически срабатывает. https://devcenter.heroku.com/articles/django-assets

Спасибо

Ответ 2

С DEBUG=False, какие оригиналы, используемые для работы, больше не работают для меня.

Однако исправление, разрешив whitenoise на MIDDLEWARE в settings.py, решило его. Лучше всего быть ниже SecurityMiddleware.

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware', # add this line
    #Other middleware...
]

`` `

В соответствии с docs его необходимо включить в первую очередь.

Ответ 3

для BASE_DIR вам нужно двойное имя, если ваши настройки не находятся в корневом каталоге, а в /projectname/folder:

settings.py

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
# for /static/root/favicon.ico    
WHITENOISE_ROOT = os.path.join(BASE_DIR, 'staticfiles', 'root') 

template.html

{%  load staticfiles %}
<link rel="stylesheet" href="{%  static "app/css/font.css" %}">

дерево приложений для этого примера:

annuaire
|-- /annuaire
|-- -- /settings.py
|-- /app
|-- /static/app/css/font.css

Ответ 4

Я боролся пару часов, пока, наконец, не понял проблему. Основная проблема, на мой взгляд, заключается в том, что в официальной документации Heroku они используют промежуточное программное обеспечение в старом стиле, которое использует MIDDLEWARE_CLASSES который устарел, вместо новой настройки MIDDLEWARE.

В белой версии 4+ опция интеграции WSGI для Django (которая включала в себя редактирование wsgi.py) была удалена. Вместо этого вы должны добавить WhiteNoise в свой список промежуточного программного обеспечения в settings.py и удалить любую ссылку на WhiteNoise из wsgi.py. (из документов)

Следующая конфигурация работала как шарм:

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'

MIDDLEWARE = [
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    # the next line of code is the one that solved my problems
    'whitenoise.middleware.WhiteNoiseMiddleware',

]

Обратите внимание на следующее примечание, также из документов.

Возможно, вы найдете другое стороннее промежуточное программное обеспечение, которое предполагает, что ему следует предоставить самый высокий приоритет в верхней части списка промежуточного программного обеспечения. Если вы точно не понимаете, что происходит, вы должны игнорировать этот совет и всегда размещать WhiteNoiseMiddleware над другим промежуточным ПО.

Ответ 5

Проблема в том, что приложение Python в Heroku использует встроенный веб-сервер и не обслуживает статические файлы.

Вы можете использовать приложение whitenoise, это рабочее решение на 100%.

Предположим, что вы уже создали статические файлы, например:

$ python manage.py collectstatic

Затем вам нужно сделать следующее:

1) $ pip install whitenoise

2) добавьте строку "whitenoise == 3.3.0" в requirements.txt

3) добавьте код в settings.py

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

4) добавьте этот код в app/wsgi.py

from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)

Ответ 6

В дополнение к вышеприведенным ответам также может быть, что вы не указали правильный STATIC_ROOT, как описано в https://docs.djangoproject.com/en/2.0/howto/static-files/#deployment

Для меня решение добавило это к концу моего setup settings.py

STATIC_ROOT = "/app/static/"

Чтобы узнать, где находится ваша статическая папка в вашем герое, выполните

heroku run python manage.py collectstatic

Затем вы увидите путь, который будет показан там.

Ответ 7

Для меня после работы.

settings.py

DEBUG = True

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') #this is not used
# Add static folder to STATIC_DIRS
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

urls.py

from django.conf.urls.static import static
from django.conf import settings

urlpatterns = [

] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Примечание

Эта вспомогательная функция работает только в режиме отладки и только если данный префикс является локальным (например,/static/), а не URL (например, http://static.example.com/).

Также эта вспомогательная функция обслуживает только фактическую папку STATIC_ROOT; он не выполняет поиск статических файлов, как django.contrib.staticfiles.

Ответ 8

У меня была такая же проблема. Самый простой способ найти проблему - это использовать

heroku run ls staticfiles/images

если изображения находятся в каталоге, где ваши файлы должны быть. Это даст вам список всех файлов в этом каталоге.

Как я выяснил, это была проблема с расширением файла. Файл имел расширение .JPG и я ссылался на него в шаблоне с расширением .jpg