2

I've set up a Django project deployed on Heroku using the Heroku Django project template. Heroku's template uses whitenoise to collect static files in a /static/ directory located on my project root.

This is great for my production environment; Heroku runs "manage.py collectstatic" each time I push new files to my server. However, it's a pain when developing locally: every time I change my static files (e.g., css), I have to manually run "python manage.py collectstatic" before seeing changes on my development server.

Is there an easy way to disable whitenoise on my local machine so that I don't have to run "python manage.py collectstatic" every time I want to see changes to local static files?

I've tried creating a separate "development_settings.py" file and removing all references to whitenoise in that file, but it doesn't work because whitenoise is still referenced in wsgi.py, which causes errors.

Sam
  • 1,952
  • 1
  • 18
  • 31

4 Answers4

2

WhiteNoise has a setting called WHITENOISE_AUTOREFRESH for exactly this reason.

From the WhiteNoise Docs:

WHITENOISE_AUTOREFRESH: Rechecks the filesystem to see if any files have changed before responding. This is designed to be used in development where it can be convenient to pick up changes to static files without restarting the server. For both performance and security reasons, this setting should not be used in production.

The default setting of this is the value of settings.DEBUG so it should be on by default if you're running a development server.

Daniel van Flymen
  • 10,931
  • 4
  • 24
  • 39
1

It looks like the default Heroku template specifies an old version of WhiteNoise. If you run

pip install --upgrade whitenoise

you should find it automatically picks up changes to your static files when in development (i.e. when settings.DEBUG is True).

D. Evans
  • 3,242
  • 22
  • 23
0

Although I didn't find an easy way to disable whitenoise on my development server, I did find a convenient workaround for making this whole process easier:

Add a new command alias to your .bash_profile file (or bin/activate if you are using a virtual environment for development) that both runs collectstatic and launches a server at the same time:

alias launch='python manage.py collectstatic --noinput; foreman start'
Sam
  • 1,952
  • 1
  • 18
  • 31
0

The current version of whitenoise will pick up changes in your static files automatically. But it can slow down the startup of runserver quite a bit, as it will iterate over all static files. I fixed this by disabling whitenoise in runserver. Now my wsgi.py looks like this:

import os
import sys

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "...")

application = get_wsgi_application()

# guess whether this is a runserver invocation with staticfiles
has_staticfiles = False
if 'runserver' in sys.argv:
    from django.conf import settings
    import inspect
    if settings.DEBUG:
        has_staticfiles = any(
            "django/contrib/staticfiles/management/commands/runserver"
            in x[1]
            for x in inspect.stack())

if has_staticfiles:
    print('runserver with staticfiles detected, skipping whitenoise')
else:
    # Do not use whitenoise with runserver, as it's slow
    from whitenoise.django import DjangoWhiteNoise
    application = DjangoWhiteNoise(application)
Chronial
  • 66,706
  • 14
  • 93
  • 99