Simplify Serving Static Files In Django with Whitenoise

What exactly are static files?

Static files like CSS, JS, and website images remain the same while the app is running; they are not processed and they don't change, hence the name, static files.

While these files are served by Django's default setup when using the development server, in production, these files must be configured properly to ensure they are read correctly.

There are a few ways to do this, a few examples being

  1. Using a web server like Nginx
  2. AWS S3 object storage and buckets
  3. Cloudinary media files

However, these methods require more complicated setup processes as well as the necessity to sign up to services and creating accounts. Not to mention I have run into countless problems with these methods that were difficult to debug, especially when deployment deadlines were creeping in.

To keep things simple and located all within the confines of your Django application, Ive preferred just opting for the very handy Whitenoise package. The setup is simple, the debugging is easy and the testing is seamless.

Lets me show you how to set up Whitenoise and test its effectiveness.

1. Install the package

pip install whitenoise

2. Configure staticfiles

The next step we need to take is to add some extra settings in the settings.py file.

Tell Django to ignore default staticfiles settings:

In the INSTALLED_APPS insert - ‘whitenoise.runserver_nostatic’ - add before Django's default staticfiles modules.

MIDDLEWARE = [
    # ...
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ...
]

Declare the static root:

STATIC_ROOT = BASE_DIR / 'staticfiles'

This means when we run a command, collectstatic files. Every static file in our project will be contained in our staticfiles folder.

Declare static files directories:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

Now we must set the settings staticfiles storage:

STORAGES = {
    # ...
    "staticfiles": {
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
    },
}

On older than Django 4.2

STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Run the following command:

python manage.py collectstatic

Once this command is run, the staticfiles folder is created. When opened, you can see all the folders/files created related to your static files throughout your Django application.

When you deploy, rest assured that all your JS/CSS will function properly as they are locally.

How can we be certain that Whitenoise is serving our static files?

To disable Django's static file handling when the development server is running, you can use the --nostatic flag:

python manage.py runserver --nostatic

Before integrating Whitenoise, no static files will be served, except for the admin page. However, after Whitenoise is integrated, you can see that Whitenoise is now serving the static content and not the default Django settings.

To double-check that Whitenoise is serving the static content, run Django with the Gunicorn server:

gunicorn django_static.wsgi:application --bind 0.0.0.0:8000

You can see that static files will not render. When you integrate Whitenoise and run the app with Gunicorn, static files will now render, allowing Django to independently serve its static files in production.

For more information on the setup visit the official whitenoise documentation.

Hopefully, this helps anyone experiencing issues with their static files not loading in production. It can be especially useful for those struggling to understand why their S3 bucket is not working or why the Cloudinary CSS is being read is an old cached version.

Avatar for DarrachBarneveld

Written by DarrachBarneveld

Addicted to building

Loading

Fetching comments

Hey! 👋

Got something to say?

or to leave a comment.