在Heroku上找不到Django静态文件(带有whitenoise)

时间:2016-02-19 14:01:28

标签: python django heroku django-staticfiles

这个问题好像有几次被问到,但我无法解决。

我使用DEBUG = False在制作中部署了django应用。我设置了allowed_host。 我使用{% load static from staticfiles %}加载静态文件。我正好写了Heroku doc提取的设置:

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)

9 个答案:

答案 0 :(得分:5)

我明白了。我需要补充一下     python manage.py collectstatic --noinput; 在我的Procfile中。 Heroku doc说collecticstatic是自动触发的。 https://devcenter.heroku.com/articles/django-assets

由于

答案 1 :(得分:2)

使用DEBUG=False,原件用于工作对我不起作用。

但是,whitenoise MIDDLEWARE上的settings.py启用了SecurityMiddleware解决方法。最好低于MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', # add this line #Other middleware... ]

std::ifstream csvFile;
csvFile.open(fileName);

```

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

答案 2 :(得分:1)

对于BASE_DIR,如果您的设置不在根目录中但在/ projectname /文件夹中,则需要一个双dirname:

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

答案 3 :(得分: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 并且它将在服务器上运行。

答案 4 :(得分:0)

问题是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)

答案 5 :(得分:0)

除上述答案外,您还可能没有指定正确的 STATIC_ROOT ,如https://docs.djangoproject.com/en/2.0/howto/static-files/#deployment

中所述

对我来说,解决方案是将其添加到我的生产settings.py

的末尾
STATIC_ROOT = "/app/static/"

要知道你的heroku运行中的静态文件夹的位置

heroku run python manage.py collectstatic

然后你会看到那里显示的路径。

答案 6 :(得分:0)

对我来说工作。

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。

答案 7 :(得分:0)

我费了好几个小时才终于找到问题所在。我认为主要的问题是,在Heroku official documentation中,他们使用的旧式中间件使用了已弃用的MIDDLEWARE_CLASSES,而不是新的MIDDLEWARE设置。

  

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

以下配置非常有用:

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

答案 8 :(得分:0)

我遇到了同样的问题。找到问题的最简单方法是使用

heroku run ls staticfiles/images

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

我发现这是文件扩展名中的一个案例问题。该文件具有扩展名.JPG,我在模板上以扩展名.jpg引用了它