Handling static files with Django

Published September 2, 2008

When I started developing in Django, I had absolutely no idea about how to handle static media files. The official documentation is very sparse on this particular topic and the only fact I got out of it is that Django shouldn't serve them directly as it is very inefficient and insecure (James Bennett wrote a great post about this topic).

I've learned a lot during the past months and in this post I'm going to explain how I handle static media files.

Development

You might've noticed the MEDIA_URL variable in your project's settings.py. It specifies the URL where the files should be served from. I prefer to create a "static_media" directory in the project's one and point the MEDIA_URL to it:

MEDIA_URL = '/static_media/'

In most cases it's okay to serve static files through Django during development. The following code-snippet will serve the "static_media/" directory through Django's static view.

if settings.DEBUG:
    urlpatterns += patterns('django.views.static',
    (r'^static_media/(?P<path>.*)$', 
        'serve', {
        'document_root': '/path/to/static_media',
        'show_indexes': True }),)

The "static_media/" directory is where you can put all your media files. When making use of them, make sure you output the MEDIA_URL before it. For example, to include a stylesheet in a template:

<link rel="stylesheet" href="{{ MEDIA_URL }}base_min.css" type="text/css" media="screen">

Production

After you've uploaded the files to a server, make sure to adjust the settings.py file in your production environment and point the MEDIA_URL to the URL where the media files are.

In my case, I pointed the MEDIA_URL to "http://media.arthurkoziel.com/" which is simply a directory served by an separate apache process.

MEDIA_URL = 'http://media.example.org/'

Now your media files will be served by Django's static view in your development environment and though another webserver/process in the production environment.

The above example with the css file will resolve into the following URL's:

Simply by changing the MEDIA_URL. Remember to sync your local static directory with your production one.

That's it, I hope at least some people found this post useful.

Comments

Jer on September 4, 2008
Thank you so much for this post! I have been very confused by the the MEDIA_URL and MEDIA_ROOT settings. They documentation doesn't explain how to use them at all. Thank you for laying it all out.

Reply

James on September 5, 2008
Thanks for the {{media_url}} trick on the template. I got to try it. will the media_url be available with doing anything?

Reply

Arthur on September 6, 2008
Yes the MEDIA_URL will be in your RequestContext as long as the "django.core.context_processors.media" is in your TEMPLATE_CONTEXT_PROCESSORS setting (which it is by default).

Reply

Alex on September 6, 2008
Thanks a lot for this article. Clear and useful!

Reply

leafar on September 12, 2008
You have a stray brace after "'/path/to/static_media')," ;)

Reply

Arthur on September 13, 2008
Fixed, thanks!

Reply

Reply