Last Updated: February 25, 2016
·
2.145K
· keithio

Django static files... catching the unicorn

Anyone who has worked with Django understand the headache that is static files. While the built-in staticfiles package is great, it does not play nicely with CDNs such as Amazon's S3. After very little digging, one can find django-storages, but the documentation is severely lacking. Hopefully this helps.

Note: I am assuming you are already operating in a virtual environment.

Steps

If you follow these six steps, you will be serving static files like a pro!

Step 1

Download django-storages:

$ pip install django-storages boto

Step 2

Add storages to your installed apps in settings.py.

INSTALLED_APPS = (
    ...
    'storages',
    ...
)

Step 3

Get your AWS Security Credentials. You will need the ACCESS_KEY_ID and the SECRET_ACCESS_KEY. Save these for Step 4.

Step 4

Add the following variables to your settings.py:

AWS_ACCESS_KEY_ID = 'your-access-key-id-from-step-3'
AWS_SECRET_ACCESS_KEY = 'your-secret-access-key-from-step-3'
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))

And modify the following variables in your settings.py:

STATIC_ROOT = os.path.join(SITE_ROOT, 'local_static')
STATICFILES_DIRS = (
    os.path.join(SITE_ROOT, 'static'), # Assuming your static files are in a folder named ``static``
)

Make sure you have a directory named local_static and static and that you have imported os.

Step 5

Add the following in your production settings. If you don't have separate settings for development and production, see my pro tip on the subject.

In settings.py:

if os.environ.get('PRODUCTION', False):
    AWS_STORAGE_BUCKET_NAME = 'static.mydomain.com'
    DEFAULT_FILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    STATICFILES_STORAGE = DEFAULT_FILES_STORAGE
    AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME

The AWS_S3_CUSTOM_DOMAIN setting is optional. If you name your S3 bucket static.mydomain.com, you can create a CNAME to static.mydomain.com that is an alias for static.mydomain.com.s3.amazonaws.com. Then, you can serve your production-ready static files from your own domain!

Step 6

Add the static files URL patterns.

In urls.py:

from django.conf.urls import patterns, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = patterns('',
    ... # Your patterns
)

urlpatterns += staticfiles_urlpatterns()

Summary

So what did we do? We implemented a method so that we can use to serve static files from the development server locally and from the production server using Amazon S3. This is great because we have quick access to our static files, e.g., *.html, *.css, *.js, while developing; but we can serve them from a CDN to reduce costs and improve performance.

Furthermore, we can send any files uploaded by users directly to the CDN, which is a critical need when using certain PaaS's such as Heroku.