a blog about Django & Web Development

How to Add CSS to a Django Project

Learn how to link your Django templates to your CSS files.
Before and After picture. The before picture on the left has a web page with some movie posters but no CSS. On the right is a picture of the same list of movies, but styled with CSS.

Adding CSS to a Django project is something that should be easy, yet I usually get stuck and rely on previous projects to provide the settings to copy and paste.

Django classes CSS as a static asset. In layman’s terms, static assets are the files that get served on the front-end like CSS, JavaScript and images. They are unaffected by the requests and responses going to and from the back-end.

During development, static files are usually stored locally, but in production they can be stored remotely in somewhere like an AWS S3 bucket or on Cloudinary.

In this article, I’m going to focus on delivering CSS stored locally. Perhaps you are getting your templates set up and need to find a way to get Django to pick up your stylesheets.

I’m going to talk about two methods in this article.

If you want to get your CSS in straight away with minimum hassle, then choose the first method, which I call the quick way.

If you’re beginning a large project and conscious about how your folders are organised, then go for the second method, which is my own preference.

Method 1: The quick way

This way involves just two lines of code. It works best if you’re working on a small project with just one app and want to load in some CSS with minimum hassle.

Check your settings

Check you have STATIC_URL defined like this in your settings.py:

STATIC_URL = 'static/'

Directory structure is important

Create your CSS file. Make sure the static and templates directories are located inside your app like the diagram here:

Without changing your project settings, Django is very inflexible about where you put your templates and static directories. If you follow these steps and still can’t get it working, the issue is likely in the folder structure.

Edit your template

  1. Go to your base.html file and put {% load static %} on Line 1 (see gist below).
  2. In base.html, link to your stylesheet. See Line 8 of the gist.

Method 2: My preferred way

The quick way is great for small projects, but is less intuitive if you have multiple apps that share some templates and CSS.

My preferred way is to put all templates for all apps in a single folder at the project root (same directory as manage.py). I like this because it gives a bit of separation between front and back end and you don’t need to keep track of which apps contain which assets.

This way takes a few more steps to set up.

Set up your folders

Start by moving your static and and templates folder out of your app and into the root directory.

A diagram of the folder structure for this method. In the quick method, the static and templates directories were located in the folder of the movies app. In this method, I've moved them out into the root folder.
I prefer to keep templates for all apps in one folder- makes them a bit easier to manage.

Tweak your project settings

We’ve got two things to do in settings.py

  1. Change where Django looks for templates
  2. Change where Django looks for static files

Update Template Settings

Go into settings.py and find TEMPLATES . Change the value of DIRS from an empty list to [BASE_DIR / 'templates']. This will instruct Django to look the templates folder of the base directory.

If you’re wondering why there is a forward slash between BASE_DIR and ‘templates’, this is because BASE_DIR is an object of type PosixPath, which is a class used to describe file system paths. You can read more about it here.

Update Static Settings

Update your static settings so it looks like this:

STATIC_URL = '/static/'

STATICFILES_DIRS = [
    BASE_DIR / 'static'
]

Update your Template

See the gist in the instructions for the quick way. You need to include {% load static %} at the top of your file and add a <link> for the stylesheet.

Check your views

As we have changed the folder structure of our templates, the render(...) methods in our views need to point to the correct location.

Because I have added sub-folders to the templates directory, I just need to reflect this in the view:

Before

return render(request, "movies_list.html", context)

After

return render(request, "movies/movies_list.html", context)

Conclusion

CSS is stored a folder called ‘static’. By default, Django looks inside apps for static assets. If you want to link your CSS without changing any settings, be sure to place your static folder inside an app.

You can have more control over where you place your templates and static content, but you will need to update your project settings so that Django knows where to look.

In both cases, loading CSS requires you to include a line {% load static %} at the top of your HTML files and provide a link to the stylesheet using the <link> tag.

Related Posts

To Do List Part 4

To Do List – Part 4: Adding a form

Step 1: Create a form class Django takes an object orientated approach to forms. The form classes can give you functionality including: Rendering entire forms