Django staticfiles documentation

Tags: django

At the Django sprint in Utrecht (NL), I’m working on the Django staticfiles documentation (see ticket 19582). To get my own thoughts sorted out, I’m trying to rewrite the existing HOWTO here in this blog entry :-) Very short, of course. Mostly to figure out a working structure.

A funny thing happened when writing it: I learned new things. We’re sprinting on the staticfiles docs with four people and each one sees different new things. I personally didn’t know the {% static "app/logo.png" %} template tag existed to help you with custom backends. And I did take a look at those custom storage backends at the same time as I hadn’t really looked at them before.

Anyway, here’s a short howto on Django’s staticfiles:

Managing static files (css, javascript, jpg)

Your website will probably include images and css files. Django provides django.contrib.staticfiles to help you manage them.

Note: the term static files differentiates them from the files that are uploaded to your site (though FileField, for instance). Those uploaded files are called media files. You’ll see the difference in some of the settings.

Using django.contrib.staticfiles

By default, Django looks for static files in directories called static/ inside your apps and site, in the same way as it looks for templates in directories called templates/. So create the directory for your static files:

your_app/
    models.py
    views.py
    templates/
        your_app/
            your_template.html
    static/
        your_app/
            logo.png
            style.css

To prevent conflicts between apps, normally a subdirectory inside static/ is used.

Django looks in those static/ directories because of the finders included in the default STATICFILES_FINDERS setting. The second enabled-by-default finder looks in the directories configured in STATICFILES_DIRS, but that list is normally empty.

Before you can use the static files, you need to tell Django the URL you want to use for them. Add a STATIC_URL setting to your settings file:

STATIC_URL = '/static/'

Note that the trailing slash is mandatory!

In your templates, use the {% static %} template tag to refer to the files:

{% load staticfiles %}
...
<img src="{% static "your_app/logo.png" %}">

Note that you should load staticfiles first, as happens on the first line.

When using Django’s build-in runserver, this is all you need to do. When deploying the site, you generally want to let the webserver serve your static files. This is explained in the next section.

Deployment configuration

When deploying Django on your webserver, staticfiles provides a manage.py collectstatic command that collects all static files and places them in a single directory. You need to tell Django about that directory with the STATIC_ROOT setting. And of course you need to tell your webserver about it.

First add the STATIC_ROOT to your settings file:

...
STATIC_URL = '/static/'  # We configured that one before.
STATIC_ROOT = '/srv/yoursite/static_stuff/`
...

Then run the collectstatic command on your webserver:

$ python manage.py collectstatic
copying ...

All your files are now collected into the directory you configured as STATIC_ROOT. You now have to configure your webserver. For NGINX, an example would be:

server {
    server_name your.site.domain.name;
    ...
    location /static/ {
       alias /srv/yoursite/static_stuff/;
       expires 1h;
    }
    ...

The /static/ in the location parameter is the same as the STATIC_URL; the alias in this example is the same as the STATIC_ROOT. The method is similar for Apache and other webservers.

Update: there are also static files storages, for instance the CachedStaticFilesStorage that hashes your filenames so that you can cache them indefinitively. (I personally don’t use that, as I use django-compressor which does more or less the same and also combines css/js files.)

Closing comments

This is not the real howto :-) I left out parts. Perhaps some will be copy/pasted into the real one. In any case, this is a useful blog entry as-is.

Some of the things we’re doing now at the sprint:

  • Split the server-side part of the howto off into a separate document.

  • Rework the rest of the howto to be more clear and useful. Remove cruft.

  • Add staticfiles to the main Django tutorial! Woohoo!

  • Update the reference doc.

Update: we’ve got a pull request for the howto. And there’s one for the new tutorial. Woohoo!

 
vanrees.org logo

Reinout van Rees

My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):