CSS auto reload with Django templates

Have you ever been in the situation where you’ve updated your CSS file but users’ web browsers haven’t automatically loaded the new one? The reason is because many web browsers cache the stylesheet for faster future reloading. Obviously you don’t want to have to get your users to Ctrl-F5 every time you update your stylesheet so here’s a little tip for making this automatic in your Django templates.

Let’s say you have a template with the following line:

<link rel="stylesheet" type="text/css" href="/site_media/css/style.css" />

Every time the page loads the browser cache will think it’s seen the file before and reload the cached version from disk. One solution is to dynamically generate the link so that the browser thinks it is loading a new file every time. One way to do this without actually making a new file every time (you could just rename your CSS file every time you update it, but that’s painful) is to pretend you’re passing some parameters to the CSS file, like this:

<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?12345" />

The trick is to generate a new fake parameter every time the page loads. Django templates make this easy by allowing us to generate a Unix timestamp (the number of seconds since a specific point in history) which we can attach to our link.

To do this we use the “now” template tag. In your template file, update the stylesheet line to the following:

<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?{% now "U" %}" />

This will generate a line like the following every time the page is loaded:

<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?1249948982" />

Voila! Automatically-refreshing stylesheets. You don’t have to make any changes to your stylesheet to use this.

This is a little inefficient, and if you have a super busy site and a very big stylesheet this could add an extra fair bit of bandwidth usage to your server(s). To get around this you could just change the “now” tag usage to generate a daily stamp (see the “now” tag docs), e.g. style.css?20090712, in which case the client browser should only reload it once per day.

One response to CSS auto reload with Django templates

You could also use os.stat to get the last modification date of the css file, then use that as the parameter. That way you’ll only trigger a forced reload when the file is actually changed, and save some bandwidth.

You might want to cache the os.stat info and only check the file every X minutes to keep from doing a disk io every time the css file is referenced.

Leave a Reply