Writing your first Django app, part 6

This tutorial begins where Tutorial 5 left off. We’ve built a tested Web-poll application, and we’ll now add a stylesheet.

Customize your app’s look and feel

Aside from the HTML generated by the server, web applications generally need to serve additional files — such as images, JavaScript, or CSS — necessary to render the complete web page. In Django, we refer to these files as “static files”.

First, create a directory called static in your polls directory. Django will look for static files there, similarly to how Django finds templates inside polls/templates/.

Django’s STATICFILES_FINDERS setting contains a list of finders that know how to discover static files from various sources. One of the defaults is AppDirectoriesFinder which looks for a “static” subdirectory in each of the INSTALLED_APPS - this is how Django knows to find the polls static files by default, including for the admin site.

Within the static directory you have just created, create another directory called polls and within that create a file called style.css. In other words, your stylesheet should be at polls/static/polls/style.css. Because of how AppDirectoriesFinder staticfile finder works as described above, you can refer to this static file in Django simply as polls/style.css, similar to how you reference the path for templates.

Static file namespacing

Now we might be able to get away with putting our static files directly in polls/static (rather than creating another polls subdirectory), but it would actually be a bad idea. Django will choose the first static file it finds whose name matches, and if you had a static file with the same name in a different application, Django would be unable to distinguish between them. We need to be able to point Django at the right one, and the easiest way to ensure this is by namespacing them. That is, by putting those static files inside another directory named for the application itself.

Put the following code in that stylesheet (polls/static/polls/style.css):

li a {
    color: green;

In your template, load the {% static %} template tag from the staticfiles template library with {% load staticfiles %}. Then, use {% static %} template tag to generate the absolute URL of the static file. Add the following at the top of your polls/templates/polls/index.html:

{% load staticfiles %}

<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />

That’s all you need to do for development. Reload http://localhost:8000/polls/ and you should see that the poll links are green (django style !) which means that your stylesheet was properly loaded.

See deploying static files for more information.

Adding a background-image

We will create a subdirectory for images. Create an images subdirectory in the polls/static/polls/ directory. Inside this directory, put an image called background.gif. In other words, put your image in polls/static/polls/images/background.gif.

Then, add to your stylesheet (polls/static/polls/style.css):

body {
    background: white url("images/background.gif") no-repeat right bottom;

That’s all you need for the development server. Reload http://localhost:8000/polls/ and you should see the background loaded in the bottom right of the screen.

See deploying static files for more information.


Of course the {% static %} template tag is not available for use in static files like your stylesheet. You should always use relative paths to link your static files between each other, because then you can change STATIC_URL later on. Also, remember this general best practice: never hardcode absolute paths.

Those are the basics. For more details on settings and other bits included with the framework see the static files howto and the the staticfiles reference.

What’s next?

The beginner tutorial ends here for the time being. In the meantime, you might want to check out some pointers on where to go from here.

If you are familiar with Python packaging and interested in learning how to turn polls into a “reusable app”, check out Advanced tutorial: How to write reusable apps.