Matthew Conlen is working as a graphics editor at the New York Times and completing a computer science Ph.D at the University of Washington.
Writing
Django+Heroku: Multiple methods of serving static files
March, 2013

During my move to Heroku, I learned a few things about the quirks of their django hosting. In particular, the official documentation about the serving of static files isn't too useful. Luckily, I found some helpful blog posts documenting this. They basically seemed to fall into two camps:

  1. Use the django server itself for the static files
  2. Use a separate service like AWS to serve the static files.
Below I talk about the pros and cons of each method, and how to implement a combination of both of them.

1. Static files via the Django Server

This blog post covers how to do this very well: http://matthewphiong.com/managing-django-static-files-on-heroku

Pros:

  • * easy to implement
  • * static files are served from same domain (no issues with CORS, etc.)
Cons:
  • * inefficient, the django server isn't really made to be serving these kinds of files
  • * not tied to additional services

2. Static files with AWS 

A great guide to implementing this is here: http://offbytwo.com/2012/01/18/deploying-django-to-heroku.html

Pros:

  • * speed. aws is very fast
  • * feel good about doing things the 'right' way

Cons:

  • * additional set-up time
  • * can cause CORS issues

Implementing Both

I recommend that you use AWS as much as possible. For me, I had all of my files on AWS, but this was causing some issues when I wanted to host files that javascript wanted access to - specifically I wanted to load up some images and use processing.js to do some visual manipulation on them.

The secret to implementing both of them is to use two separate settings files.

Keep your aws settings in the regular settings.py file, and create a second file, call it settingsnoaws.py and set it up like you would via the blog post in section 1. 

Now, the post in section one has you manipulating the Procfile by prepending a collectstatic command to it. We are going to change that command slightly:

python manage.py collectstatic --settings=<python module name for settingsnoaws.py>

Replace <python module name for settingsnoaws.py> with the relevant python module path (e.g. for this site it was "mathisonian.settingsnoaws").

Then, make sure you've updated your urls file to serve static files with django (as shown in the first blogpost) and use the url /static/<filename> to serve any static file you want with django.

NOTE: In this setup STATIC_URL will resolve to aws, and you will have to hardcode /static/... urls for any files you want to serve with the django server.