No Time Dad

A blog about web development written by a busy dad

Example Django Bootstrap CSS Setup

I won’t hide my love of Django. It’s the best. Usually it’s the first framework I reach for when starting a new project from scratch. Or if I’m working on a quick prototype. It just does a lot of the things that tend to take up time when starting a new project.

Along the same lines, I also like using bootstrap when building rapid prototypes or starting new projects. Similar to Django, it does a lot right out of the box. Especially with forms and buttons. So, I thought it’d be handy to do a quick write-up on my typical Django bootstrap css setup.

Downloading bootstrap

The first thing to do is download and unzip the latest bootstrap compiled CSS and JS. At the time of this writing, the latest version was 5.1. Downloading the compiled files is the quickest way to get working with Django and bootstrap.

But, it doesn’t allow for any bootstrap customization. For that, the source files are needed and custom tooling is needed to for building the assets. This is a bit more work, and I generally don’t go down this route unless I need a custom color palette. For quick prototype projects in Django this is usually not the case, so I stick to the compiled files.

Unzip the compiled files

Once downloaded, I’ll extract the files via the unzip command. I usually put the unzipped files somewhere that’s easy to find and copy over. Or I’ll just leave them in my Downloads/ directory.

unzip ~/<path to>/bootstrap-5.1.1-dist.zip

Django folder structure

At this point I need to take a look at my Django project structure and figure out where the bootstrap css and js files are going to go. Let’s assume that my Django project is called myProject and it has an app called myApp that sit inside of a root directory called rootDir. The project structure would look as follows:

| rootDir
  db.sqlite3
  manage.py
  | myProject
  | myApp

Inside of the myApp directory I’ll create a new directory called static with a child directory called myApp. Which will look as follows:

| rootDir
  db.sqlite3
  manage.py
  | myProject
  | myApp
    | static
      | myApp

Moving the bootstrap files

I generally just use the move mv command for this. But the directories can all be recursively copied if that’s easier. The main idea is that I’m moving the newly unzipped bootstrap css and js directories into the static/myApp/ directory I created above.

mv ~/<path to>/bootstrap-5.1.1-dist/css ~/<path to rootDir/myApp/static/myApp/`

And do the same thing again for the js directory:

mv ~/<path to>/bootstrap-5.1.1-dist/js ~/<path to rootDir/myApp/static/myApp/`

My folder structure should now look as follows:

| rootDir
  db.sqlite3
  manage.py
  | myProject
  | myApp
    | static
      | myApp
        | css
        | js

Creating a template html file

So, the last thing to do here is load the bootstrap css in an html file to be rendered. I like to create a base.html template in my app’s templates directory, then extend that template as needed. Which makes always loading the bootstrap css and js very easy.

If it doesn’t exist already, create a templates directory in the myApp directory and create a new file in that directory called base.html.

Below is how the contents of the file might look. It’s worth noting that Django’s load static helper is being used here along with the static tag and path the minified css.

<!-- base.html -->
{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'myApp/css/bootstrap.min.css' %}">

<div class="container">
  {% block content %}
  {% endblock %}
</div>

As a quick check, I wrap a content block in a div with bootstrap’s container selector applied.

Rendering and confirming

The base.html file created above isn’t mapped to a view yet. In fact, it probably won’t ever be mapped directly to a view and instead be extended by another template. Below is an example of a simple home page that extends the base.html file and loads the bootstrap css.

# myApp/views.py
from django.views.generic import TemplateView


class HomeView(TemplateView):
    template_name = "home.html"
<!-- home.html -->
{% extends "base.html" %} 

{% block content %} 
<div>hello!</div>
{% endblock %}

Assuming the urls.py are wired up to render the HomeView, the text “hello!” should be displayed with bootstrap’s container class applied. Which generally means the text will have a margin to the left.