I’ve praised Django Admin in the past. It’s one of the most useful features of Django.
Despite all the advantages of Django Admin, it could still use a few improvements. One such tweak is adding a navigation menu in Django Admin. This tutorial will show you how to add one.
6 October 2021
by
Kalpit Jain
Despite all the advantages of Django Admin, it could still use a few improvements. One such tweak is adding a navigation menu in Django Admin. This tutorial will show you how to add one.
When I started working with Django Admin I found it counter-intuitive to go back to homepage every time I needed to move to another module’s page. It’s something I wasn’t used to. I’m sure you’ve felt the same way (that’s why you’re here, I’m hoping!).
As developers, we’re used to navigating from one module to another directly from the navigation menu in every Admin Panel we’ve ever used. (The same goes for the client or employer you’re developing the admin panel for.) Sooner or later, you’ll likely find yourself tinkering with Django Admin templates, trying to add links to all the modules in the menu. This can get tricky.
Since the purpose of this post is to explain the procedure to add a navigation menu, we won’t be paying much attention to the design part. I’ll be using Bootstrap Navbar Component to create the UI, but you can use any other library or create your own UI from scratch.
Here’s what what our navigation menu in Django Admin will look like at the end of this tutorial:
Let’s create a new Django Project first.
Creating a Django Project
I’m using Python 3.6 and Django 2.1, but these instructions are more or less similar for other recent versions of Python & Django.
Create a new directory and execute the command below to create a python virtual environment, and activate it.
# Creates a virtual environment in subdirectory "venv"python -m venv venv
# Activate itsource venv/bin/activate # LinuxvenvScriptsactivate # Windows
While you’re in the virtual environment, install Django.
pip install Django # to install the latest stable releasepip install Django==2.1 # to install a specific version
Once installed, you may configure the database and other settings. Without diving deeper into the setup instructions, let’s quickly create a project and fire up the development server.
django-admin startproject navbar # create a Django project
python manage.py migrate # run migrations
python manage.py createsuperuser # create a super user
python manage.py runserver # start the development server
Now, when you navigate to http://127.0.0.1:8000/ it should show you Django’s default welcome page.
To access the admin panel, go to http://127.0.0.1:8000/admin/ then login using the credentials you created with python manage.py createsuperuser command.
This is what you get out of the box. A fully functional Django Admin — without navigation menu bar.
Add Bootstrap Dependencies
Now that we have a functional Django Admin, let’s add a navigation menu.
We won’t be writing any Python/Django code yet. We’ll just replace Django Admin’s default header with a static bootstrap Navbar.
First create a new app. Creating a separate app has its benefits. I’ll cover that in a bit.
python manage.py startapp my_admin
Once done, create directories /templates/admin in my_admin app. Copy default Django Admin’s base.html and base_site.html to this directory.
In my case the default directory was found at /venv/Lib/site-packages/django/contrib/admin/templates/admin/.
We’ll be working on the newly copied files, i.e. files in /my_admin/templates/admin/.
Now, to use bootstrap Navbar, first we need to add relevant bootstrap CSS and JavaScript files. To do so, download bootstrap source files from their official website. We’re downloading source files because we won’t be using all features of Bootstrap. We’ll be using SASS preprocessor to pick only the parts we need.
Extract the downloaded files to /my_admin/static/admin/
With that completed, let’s start editing some HTML.
Open /my_admin/templates/admin/base.html and add the following snippet in the <head> section to add bootstrap CSS. Make sure you write correct path to bootstrap.scss file.
Since we just need the Navbar component, you can remove the imports from bootstrap.scss which are not required, otherwise it might conflict with existing Django CSS. Here’s my version of bootstrap.scss for reference:
You may have noticed that we’re using .scss files in HTML directly, and the compress block is not supported by Django out of the box. If you’re using lint checks, your code editor is probably showing warnings by now.
This tag is provided by django-compressor to process .scss (and other) files. You may choose to use any other library or none at all. For the sake of this tutorial we’re using django-compressor.
To install and configure Django Compressor, follow these steps:
Run pip install django-compressor django-libsass while you’re in Python virtual environment.
Add COMPRESS_PRECOMPILERS = ((‘text/x-scss’, ‘django_libsass.SassCompiler’),) to settings.py.
Add the following in settings.py:
STATICFILES_FINDERS = (‘django.contrib.staticfiles.finders.FileSystemFinder’,‘django.contrib.staticfiles.finders.AppDirectoriesFinder’,# other finders..‘compressor.finders.CompressorFinder’,)
Detailed installation instructions of Django Compressor are available on readthedocs.
. . .
Adding Navbar HTML
Now, let’s replace the default header with Bootstrap Navbar. Don’t bother with Django code yet, we’ll make the menu dynamic in next section. Delete (or comment out) the existing header code, it looks similar to this:
Run the development server again, then navigate to Django admin. It works, right?
There’s a tiny issue though. If you navigate to any other page except the homepage, the navigation menu shows different items based on the current page. We did all this effort to show a menu with all items at all pages, didn’t we? Let’s fix that.
Showing All Apps In Navigation Menu in Django Admin
We’re using app_list tag provided by default in Django, but it does not return all apps’ list at all times. It takes current page as context, and modifies the result accordingly. The solution? We need a custom tag which can return all items at all times.
Create a python package named templatetags in my_admin app, and create a file utils.py in it. Paste the following code in this file.from django import template
You might be tempted to edit the core files directly or not using existing Django template blocks, but the advantage of the above approach is that we get a modular standalone app. You can literally use this app with any standard Django Admin project and you’ll get a working navigation menu bar with no extra efforts.
We’ve used bootstrap in this tutorial to avoid spending time in creating UI. In your project you may use any other navigation menu component or create your own component from scratch.
What we are essentially doing is getting list of apps from our custom template tag and showing them in the menu as links. You can use the same approach and create material design drawer menu instead of Navbar! The best part is that you can override any part of Navbar as you would have done with default Django Admin template.
Were you able to create Navbar easily using this tutorial? Do you have any other tips to improve this tutorial? Let me know your experience in comments below.