There are a lot of moving parts underneath the hood of a Django web application. Much of it is very transparent to the user of the site, but it is important for the web developer to know how things are working in order to understand how to debug problems. Django has a Debug Toolbar you can install to allow full inspection of the Django environment during development. Once installed, if you load your web application locally you’ll see a myriad of information on a debug panel that now displays itself on the right-hand side of your browser. In this tutorial, we are going to install the Django Debug Toolbar and use it to inspect things like settings, headers, HTTP requests, SQL queries, static files, templates, signals, and more.
Install Django Debug Toolbar
Installing the debug toolbar is very easy. The first step is to simply use pip to add the python package to your system. At the command line, enter pip install django-debug-toolbar.
djangotutorial $pip install django-debug-toolbar Requirement already satisfied: django-debug-toolbar
We had already installed the toolbar so we get the message that the requirement is already satisfied. Great!
Configure The Debug Toolbar
Installing the python package on your machine is not enough to get the debug toolbar to display in your web browser. We need to configure the debug toolbar within Django settings to activate it. This is done in the settings.py file and the urls.py file.
djangotutorial/settings.py
In our settings file, we made the highlighted changes below. These are in the INSTALLED_APPS, MIDDLEWARE, and INTERNAL_IPS variables.
"""
Django settings for djangotutorial project.
Generated by 'django-admin startproject' using Django 3.0.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'n_x6notgo^4gs&real$zlnxsillyf(r187d6#q=)wqx4rt0!q'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'djangodogs',
'debug_toolbar'
]
MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware'
]
ROOT_URLCONF = 'djangotutorial.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
WSGI_APPLICATION = 'djangotutorial.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static')
]
INTERNAL_IPS = [
'127.0.0.1'
]
djangotutorial/urls.py
In the urls.py, we just need to make a few edits. Here is how we configured ours.
from django.contrib import admin
from django.urls import include, path
from djangodogs import views
import debug_toolbar
urlpatterns = [
path('__debug__/', include(debug_toolbar.urls)),
path('admin/', admin.site.urls),
path('', views.home, name='home'),
path('dogs/<id>/', views.dog_detail, name='dog_detail'),
]
Start Your Engines! (Servers)
Everything is in place and now we can run our python server with the python manage.py runserver command. Once the server is running, we load up the homepage of the project we have been working on recently and we see something new!
The screenshot above is the homepage of the site with the new Django Debug Toolbar being displayed on the right-hand side. As you can see, it offers several panels like Versions, Time, Settings, Headers, Request, SQL, Static Files, Templates, Cache, Signals, Logging, and Profiling.
Settings
The settings panel provides information about the current Django project. When you click the settings panel, all of the various project level settings are displayed.
Headers
The headers panel shows information about the request headers, response headers, and WSGI environment. All of this is useful for understanding the request-response cycle for any page in your application.
Request
The request panel has some great information about Views, Cookies, Session data, and if there are any GET or POST variables present. We are visiting the homepage here, and we can see exactly with view function is responsible for rendering the template. The view arguments, keyword arguments, and URL name are also displayed. The debug toolbar is a fantastic tool to really understand how things work in your Django application.
SQL
The SQL panel of the debug toolbar is really cool. When you click on this panel, it displays any SQL queries that were needed to provide data for the given page. In addition, in the display of the SQL queries, you can click on either the Sel or Expl buttons to run or explain the SQL query in question.
Here is an example of running one of the queries that were displayed.
So now we know that when loading the homepage of our site, one of the queries that are performed is the following.
SELECT "djangodogs_dog"."id", "djangodogs_dog"."name", "djangodogs_dog"."breed", "djangodogs_dog"."description" FROM "djangodogs_dog"
Very neat! How does this happen though? You might recall that when we built this Django project, we never actually typed out any SQL statements in the Python code. This is because Django has it’s own built-in ORM or object-relational mapper. What that means is we just have to use any of the methods provided by the Django ORM, and it runs the needed SQL query for us. So the code in our project that is producing the SQL query we see above is found in the djangodogs/views.py file. That line of code is highlighted here.
from django.shortcuts import render
from .models import Dog
from django.http import Http404
def home(request):
dogs = Dog.objects.all()
return render(request, 'home.html', {'dogs': dogs})
def dog_detail(request, id):
dog = Dog.objects.get(id=id)
return render(request, 'dog_detail.html', {'dog': dog})
As you can see, this is super useful for understanding how your Django application is interacting with the database. Additionally, as your queries to the database get more complex, and they will, you can use the debug toolbar to see the exact SQL statements that the Django ORM is sending to the database.
Get more information about the Django debug toolbar
- Setup the Django debug toolbar (medium.com)
- Django environ and Django debug toolbar/ (mattlayman.com)
- Read the Django debug toolbar docs (readthedocs.org)
- Install Django debug toolbar (qiita.com)
- How to install Django debug toolbar (bedjango.com)
- Using the Django debug toolbar (riptutorial.com)
- Django packages debug toolbar (djangopackages.org)
- Questions about Django debug toolbar (stackoverflow.com)
Django Debug Toolbar Summary
The Django Debug Toolbar is a great tool for developing with Django. It has a configurable set of panels that display all kinds of helpful debug information about your Django project. When these panels are clicked, they display detailed information as we saw in the above examples.