Heroku 上找不到 Django 静态文件(使用白噪声)

问题描述 投票:0回答:10

这个问题似乎被问了好几次,但我无法解决。

我使用

DEBUG = False
在生产环境中部署了一个 django 应用程序。我设置了我的
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)
python django heroku django-staticfiles
10个回答
10
投票

有了

DEBUG=False
,原来用来工作的东西不再适合我了。

但是,通过在

whitenoise
中的
MIDDLEWARE
上启用
settings.py
解决了这个问题。最好就在下面
SecurityMiddleware

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

```

根据docs,它实际上需要首先启用。


7
投票

我明白了。我需要添加

python manage.py collectstatic --noinput;

在我的 Procfile 中。 Heroku 文档说

collecticstatic
是自动触发的。 https://devcenter.heroku.com/articles/django-assets

谢谢


5
投票

对我来说以下工作有效。

设置.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'),
]

url.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.


3
投票

问题在于 Heroku 中的 Python 应用程序使用内置 Web 服务器,并且不提供静态文件。

您可以使用whitenoise的应用程序,这个工作解决方案是100%。

假设你已经生成了静态文件,例如:

$ python manage.py collectstatic

接下来你需要这样做:

1)

$ pip install whitenoise

2)在您的requirements.txt

中添加字符串“whitenoise==3.3.0”

3)在settings.py

中添加代码
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

4)在app/wsgi.py

中添加此代码
from whitenoise.django import DjangoWhiteNoise
application = DjangoWhiteNoise(application)

2
投票

对于 BASE_DIR,如果您的设置不在根目录中而是在 /projectname/ 文件夹中,则需要双目录名:

设置.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') 

模板.html

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

此示例的应用程序树:

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

2
投票

删除了 nsjsjbxkdndk dodnidndo dkdbdbdkd 没有。


1
投票

我苦苦挣扎了几个小时,终于找到了问题所在。我认为主要问题是在 Heroku 官方文档中,他们使用旧式中间件,该中间件使用已弃用的

MIDDLEWARE_CLASSES
,而不是新的
MIDDLEWARE
设置。

在whitenoise 4+ 版本中,Django 的 WSGI 集成选项(涉及编辑 wsgi.py)已被删除。相反,您应该将 WhiteNoise 添加到 settings.py 中的中间件列表中,并从 wsgi.py 中删除对 WhiteNoise 的任何引用。 (来自文档

以下配置非常有效:

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 置于其他中间件之上


1
投票

我也遇到过同样的问题。查找问题最简单的方法就是使用

heroku run ls staticfiles/images

如果图像位于您的文件所在的目录中。这将为您提供该目录中所有文件的列表。

我发现这是文件扩展名的大小写问题。该文件的扩展名是

.JPG
,我在模板上引用了它,扩展名是
.jpg


1
投票

$ pip 安装白噪声

在中间件中添加白噪声。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    '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',
    'whitenoise.middleware.WhiteNoiseMiddleware',
]

还需要在setting.py中添加STATIC_ROOT

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

并在urls.py中添加media_root

from django.conf import settings

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \
        + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

然后您可以在本地或服务器上运行collectstatic命令

 python manage.py collectstatic

它将正常工作。您可以在本地运行此命令collectstatic,它将在服务器上运行。


0
投票

这对我有用

我的要求.txt是

whitenoise==6.2.0
static3==0.7.0
webdav4==0.9.7
Django==3.2
# others

我删除了

STATIC_ROOT
中的
settings.py

并添加 var

STATICFILES_DIRS
,我的
 settings.py


MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    "whitenoise.middleware.WhiteNoiseMiddleware",
    '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',
]

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),
)

STATIC_URL = 'static/'

如果你设置了

heroku config:set DISABLE_COLLECTSTATIC=1
,现在你应该可以正常运行了

如果您仍然想使用COLLECTSTATIC功能 在

Procfile
文件中手动添加为:

web: python manage.py collectstatic --no-input; gunicorn my_blog.wsgi --log-file - --log-level debug

我的

my_blog.wsgi
文件是(是按照帖子配置的,现在找不到了):

import os
from django.core.wsgi import get_wsgi_application
from dj_static import Cling

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'my_blog.settings')
application = Cling(get_wsgi_application())
© www.soinside.com 2019 - 2024. All rights reserved.