Django staticfiles not found on Heroku (with whitenoise)

允我心安 提交于 2019-11-27 15:06:45

I got it. I needed to add python manage.py collectstatic --noinput; in my Procfile. Heroku doc said that collecticstatic is automatically triggered. https://devcenter.heroku.com/articles/django-assets

Thanks

With DEBUG=False, what originals use to work does not work for me anymore.

However a fix by enabling whitenoise on MIDDLEWARE in settings.py solved it. Best to be just below SecurityMiddleware.

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

```

According to the docs, it actually needs to be enabled in the first place.

for BASE_DIR you need to a double dirname if your settings are not in the root but in /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" %}">

app tree for this example:

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

I struggled a couple of hours until I finally figured out the problem. The main problem in my opinion is that in the Heroku official documentation they use the Old-style middleware that uses MIDDLEWARE_CLASSES which is deprecated, instead of the new MIDDLEWARE setting.

In whitenoise version 4+, the WSGI integration option for Django (which involved editing wsgi.py) has been removed. Instead, you should add WhiteNoise to your middleware list in settings.py and remove any reference to WhiteNoise from wsgi.py. (from the docs)

The following configuration worked like a charm:

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',

]

Pay attention to the following Note, also from the docs.

You might find other third-party middleware that suggests it should be given highest priority at the top of the middleware list. Unless you understand exactly what is happening you should ignore this advice and always place WhiteNoiseMiddleware above other middleware.

The problem is that the Python application in Heroku uses the built-in web server and does not serve static files.

You can use the app of the whitenoise, this working solution is 100%.

Suppose you have already generated static files, for example:

$ python manage.py collectstatic

Next you need to do this:

1) $ pip install whitenoise

2) add string "whitenoise==3.3.0" in your requirements.txt

3) add code in settings.py

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

4) add this code in app/wsgi.py

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

In addition to above answers, it can also be that you have not specified a correct STATIC_ROOT as described in https://docs.djangoproject.com/en/2.0/howto/static-files/#deployment

For me, the solution was adding this to the end of my production settings.py

STATIC_ROOT = "/app/static/"

To know where your static folder is in your heroku run this

heroku run python manage.py collectstatic

Then you will see the path being shown there.

For me following worked.

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)

Note

This helper function works only in debug mode and only if the given prefix is local (e.g. /static/) and not a URL (e.g. http://static.example.com/).

Also this helper function only serves the actual STATIC_ROOT folder; it doesn’t perform static files discovery like django.contrib.staticfiles.

user11760977

I have had the same issue. The simplest way to find the problem is to use

heroku run ls staticfiles/images

if images is in the directory where your files should be. This will give you a list of all the files in that directory.

As I found out it was a case issue in the file extension. The file had an extension .JPG and I referenced it on the template with an extension .jpg

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!