Mastering Django Static Files

Informal Namespacing

“If I called my app polls, then why do I put my CSS at polls/static/polls/app.css? Why do I need that second polls?”

This question, or variants thereof, comes up regularly.

So what is the point of having a second polls dir inside polls/static?

Here’s the thing – the polls/static directory is one of potentially many sources for static files. If you create polls/static/app.css, then in a template, you’d refer to it with {% static 'app.css' %}. That lookup happens across all static files of your project – just because it’s a template inside your polls app doesn’t mean it’ll prefer static files from your polls app.

Thus, if:

  • You’ve got polls/static/app.css
  • I’ve created a reusable app with myawesomeapp/static/app.css
  • You’re using my app alongside your polls app (which, of course you are, because my app’s awesome),

then one of our apps is going to end up with the other’s CSS, which is probably not what you want!

To work around this, convention is to use that extra directory:

  • You put your CSS at polls/static/polls/app.css
  • You refer to it with {% static 'polls/app.css' %} inside your templates
  • I’ll put mine at myawesomeapp/static/myawesomeapp/app.css

and then we won’t collide at all.

You’ll see the same convention happen with templates.

I call this “informal namespacing”, because there’s no actual enforcement of this – there’s nothing to stop you creating polls/static/myawesomeapp/app.css. This is, in fact, a common technique for overriding static files or templates in third party apps, for example django.contrib.admin (see the official docs on overriding admin templates).

There you go – strictly speaking you don’t need the “extra” directory, but you almost certainly want it!

Stay updated!

Sign up to receive updates on the book’s progress, advice on ways to make your app better, and sample chapters as they become available!

* indicates required

« Failproof Favicons