6- Django Base Template and Navigation Bar

By using base template, we can ensure a standard look in the project and get rid of typing duplicate HTML code. We first need to create a folder named templates in the project's root folder. Then create a new file named base.html.

 

We need to change settings.py and tell that Django about our base template. Modify DIRS key as below.

Change it to:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [(os.path.join(BASE_DIR, 'templates')),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

 

 

Visit https://getbootstrap.com/docs. Copy and paste the Starter Template into base.html

Add load static at the top. Remove <title> and add block title instead. Remove <h1> and add add block content instead like below.

base.html

{% load static%}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
{% block title %}
{% endblock title %}
    
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
  </head>
  <body>
    {% block content %}
    {% endblock content %}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
  </body>
</html>

 

 

Let's add a navigation bar into base.html from bootstrap. Search for Navbar. Choose the navbar you like. Copy and Paste the navbar code just before the </head> tag. Then customize it according to your requirements.  In the below example, I show the user MoviesApp and Home links no matter if he is authenticated or not. Notice the if else statements. If the user is authenticated he will see My List, My Account and Log Out links. If the user is not authenticated he will see register and Log In instead.

base.html

{% load static%}
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
{% block title %}
{% endblock title %}
    
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">

    <!--Navbar Starts Here-->
    <nav class="navbar navbar-expand-lg bg-light">
        <div class="container-fluid">
          <a class="navbar-brand" href="#">Movies</a>
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="navbarSupportedContent">
            <!--Home and MoviesApp links -->
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
              
              <li class="nav-item">
                <a class="nav-link active" aria-current="page" href="#">Home</a>
              </li>
              
              <li class="nav-item">
                <a class="nav-link active" href="#">MoviesApp</a>
              </li>
            </ul>

            {% if user.is_authenticated %}
            <ul class="navbar-nav">
              <li class="nav-item dropdown">
                <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                  {{user.username}}'s Profile
                </a>
                <ul class="dropdown-menu">
                  <li><a class="dropdown-item" href="#">My List</a></li>
                  <li><a class="dropdown-item" href="#">My Account</a></li>
                  <li><hr class="dropdown-divider"></li>
                  <li><a class="dropdown-item" href="#">Log Out</a></li>
                </ul>
              </li>
              <li class="nav-item">
                <a class="nav-link disabled">Disabled</a>
              </li>
            </ul>
            <!--This my search box-->
            <form class="d-flex" role="search">
              <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
              <button class="btn btn-outline-success" type="submit">Search</button>
            </form>
            {% else %}
              <a class="btn btn-outline-secondary" href="#">Login</a>
              <a class="btn btn-primary ml-2 mr-2" href="#">Register</a> 
          </div>
            {% endif %}
        </div>
      </nav>
      <!--Navbar Ends Here-->
  </head>
  <body>
    {% block content %}
    {% endblock content %}
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
  </body>
</html>

 

In MoviesApp folder create a folder named "templates" and a file named "moviesapp.html".

Edit views.py in moviesapp

#Remove This View
def moviesapp(request):
    return HttpResponse("Hello.")

#This is our new view that uses a template
def moviesapp(request):
    msg= "Hello. This view is using a template"
    return render(request, 'moviesapp.html', {'welcome_msg': msg})

 

 

Now we can just extend any template to our base template by simply adding {% extends 'base.html' %} at the top of a template. I will extend my crmapp.html template to our base and see how it looks.

moviesapp.html

{% extends 'base.html' %}
{% block title %}
    <title>Hello</title>
{% endblock title %}

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

 

Restart Apache service. This navbar will be seen on each teamplate where we extend it to use the base html. If the user is authenticated he will see the navbar with the links below.

 If the user is not authenticated, Navbar will be seen like this

FAVICON:

We can add favicon by adding the below line of code in our base.html. Create a folder named images in your static folder and copy the favicon there.

Favicon size is 16x16. Just add it before the {% block title %} 

<link rel="icon" href="/{% static 'images/favicon.ico' %}" type="image/gif" sizes="16x16">
{% block title %}
{% endblock title %}