21. February 2020
Django | Build a Dashboard with Django and Bootstrap: Part 1

This is Part 1 of Building a Dashboard with Django and Bootstrap:
- Part 1: Building a base Django project
- Part 2: Prepare for dynamic content
- Part 3: Handling navigation and the side menu
- Part 4: Deploy Django App to Azure
Introduction
Building a complete web app isn’t always an easy task. Designing and Implementing on both sides (backend and front-end) requires mostly a lot of knowledge. So, why don’t using tools or framework, which helps and makes our life easier. Django is one of these frameworks:
Django is a high-level Python Web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of Web development
So, let’s get started.
Create project
For subsequent steps, we will remember our starting directory
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">DASHBOARD_ROOT=$(pwd)
echo $DASHBOARD_ROOT
... here you will see your current folder...
First step is to create our main Django project
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">> django-admin startproject dashboard
> cd dashboard
> python manage.py migrate
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">> python manage.py runserver 8080
...
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.
View current project in browser
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">mkdir -p apps/core
python manage.py startapp Core apps/core
mkdir -p dashboard/apps/frontend
python manage.py createapp Frontend dashboard/apps/frontend
Add new apps to project
Modify name in apps/core/apps.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="3" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">class CoreConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.core'
Modify name in apps/frontend/apps.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="3" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">class FrontendConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'apps.frontend'
Modify dashboard/settings.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">INSTALLED_APPS = [
...
'apps.core',
'apps.frontend',
]
Modify dashboard/urls.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="python" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">from django.urls import path
import dashboard.apps.frontend.views as views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('admin/', admin.site.urls),
]
Create view
Modify view in apps/frontend/views.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="python" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">from django.shortcuts import render
from django.views import generic
class IndexView(generic.TemplateView):
"""
IndexView:
"""
module = 'indexView'
template_name = 'frontend/index.html'
Create template for frontend View
Create template file dashboard/apps/frontend/templates/frontend/index.html
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title=""><h1>
Frontend: Let's get started
</h1>
Add template folder to configuration
Add template folder to TEMPLATES
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="4" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
]
View current project in browser
So far, we have the following folder structure
Create admin user
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="1" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">python manage.py createsuperuser
Username (leave blank to use 'user'): admin
Email address: admin@localhost
Password:
Password (again):
Superuser created successfully.
Add Bootstrap support
Download requires files for Bootstrap, jQuery and PopperJS.
Or download this prepared archiv aund unzip the files unter dashboard
.
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="powershell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">
$ROOT = Split-Path -Parent $PSSCRIPTROOT
$global:ProgressPreference = 'SilentlyContinue'
$response = Invoke-WebRequest https://getbootstrap.com/
$downloadlink = $response.links | Where-Object { $_.href -like "*download/" } | foreach-object { $_.href } | select-object -first 1
$downloadpage = Invoke-WebRequest https://getbootstrap.com$downloadlink
$dist_download_url = $downloadpage.links | where-object { $_.href -like "*-dist.zip" } | foreach-object { $_.href }
$dist_version = $dist_download_url.split("/")[-2].replace("v","")
$dist_zip = "$ROOT\${dist_version}.zip"
write-host "Download $dist_zip from $dist_download_url"
Invoke-WebRequest $dist_download_url -O $dist_zip
write-host "Unpack to assets\vendor\bootstrap\${dist_version}"
remove-item -recurse -force static\assets\vendor\bootstrap
new-item -type directory static\assets\vendor\bootstrap > $null
expand-archive $dist_zip -destinationpath static\assets\vendor\bootstrap
move-item static\assets/vendor/bootstrap/bootstrap* static\assets\vendor\bootstrap\${dist_version}
$global:ProgressPreference = 'Continue'
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="powershell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">$ROOT = Split-Path -Parent $PSSCRIPTROOT
$version = "3.6.0"
$url_base = "https://code.jquery.com"
$destination = "static\assets\vendor\jquery\$version\js"
write-host "Prepare destination $destination"
remove-item -recurse -force $destination > $null
new-item -type directory $destination > $null
Invoke-WebRequest $url_base/jquery-3.6.0.js -O $destination/jquery-3.6.0.js
Invoke-WebRequest $url_base/jquery-3.6.0.min.map -O $destination/jquery-3.6.0.min.map
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="powershell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">
$ROOT = Split-Path -Parent $PSSCRIPTROOT
$version = "2.10.2"
$url_base = "https://cdnjs.cloudflare.com/ajax/libs/popper.js/${version}/umd/"
$destination = "static\assets\vendor\popperjs\$version\js"
write-host "Prepare destination $destination"
remove-item -recurse -force $destination > $null
new-item -type directory $destination > $null
Invoke-WebRequest $url_base/popper.js -O $Destination/popper.js
Finally, the folder structure should look like this:
Add templates path to settings
File dashboard/settings.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="5" data-enlighter-language="python" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR + '/dashboard/templates',
],
Add static path to settings
File dashboard/settings.py
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="2-4" data-enlighter-language="python" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, '/static')
]
Modify frontend view template
File dashboard/apps/frontend/templates/index.html
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="html" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">{% extends 'site/base.html' %}
{% load static %} {% block title %}Dashboard with Django and Bootstrap{% endblock title %}
{% block nav-style %}mkt-nav{% endblock nav-style %}
{% block content %}
<div class="jumbotron">
<div class="container"></div>
FRONTEND
<div class="container full"></div>
</div>
{% endblock content %}
View current status of project
For a first start, we will use this sb-admin-2 dashboard template from here:
Bootstrap templates consist of at least 3 different types of files
- main index.html page, responsible for collection all elements and set up your page
- CSS files defining the style of your page
- JavaScript files, containing needed frameworks and code
So, first start by downloading the sample template from here. Be sure, you start in our project root folder:
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cd $DASHBOARD_ROOT
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">git clone https://github.com/BlackrockDigital/startbootstrap-sb-admin-2 install/sb-admin-2
Next, find out, what we need for our template in addition to the file index.html
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cd install/sb-admin-2
grep -E "<(link|script)" index.html
<link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
<link href="css/sb-admin-2.min.css" rel="stylesheet">
<script src="vendor/jquery/jquery.min.js"></script>
<script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<script src="vendor/jquery-easing/jquery.easing.min.js"></script>
<script src="js/sb-admin-2.min.js"></script>
<script src="vendor/chart.js/Chart.min.js"></script>
<script src="js/demo/chart-area-demo.js"></script>
<script src="js/demo/chart-pie-demo.js"></script>
That’s a lot of additional files.
To keep the file structure consistent, these files should be stored under the dash/board/static folder (same as the bootstrap files before).
To achieve this, there are two possibilities:
- Create desired folder and copy each of the source files to the destination folder
- Copy the complete static folder from the github repository for this post.
We use the second option to keep the focus on creating our dashboard.
So, first, clone the repository:
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cd $DASHBOARD_ROOT/install
git clone https://github.com/rgoestenmeier/Dashboard_Django-Bootstrap
Then, copy the requred files
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cd $DASHBOARD_ROOT
cp -R install/Dashboard_Django-Bootstrap/dashboard/static dashboard
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cp -R install/Dashboard_Django-Bootstrap/dashboard/templates dashboard
Having everything needed for the dashboard template, the next step is to modify the front-end template
File dashboard/apps/frontend/templates/frontend/index.html
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="1" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">{% extends 'site/sb-admin-2/base.html' %}
{% load static %} {% block title %}Dashboard with Django and Bootstrap{% endblock title %}
{% block content %}
{% endblock content %}
View current project in browser
Still some work to do, because our dashboard is only a static dashboard. All content is programmed in the dashboard template file dashboard/templates/site/<gwmw class="ginger-module-highlighter-mistake-anim ginger-module-highlighter-mistake-type-1" id="gwmw-15824468928077326673877">sb</gwmw>-admin-2/base.html
For example, look at the cards with the earnings at the top:
This will be described in the next step: Part 2: Prepare for dynamic content
Additional Steps
Add dashboard from bootstrap example template
Get Javascript libraries
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="generic" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">DST=dashboard/static/vendor
URL=https://cdnjs.cloudflare.com/ajax/libs
mkdir ${DST}/feather/4.9.0/js
wget -q ${URL}/feather-icons/4.9.0/feather.min.js -O ${DST}/feather/4.9.0/js/feather.min.js
mkdir ${DST}//chart/2.7.3/js
wget -q ${URL}/Chart.js/2.7.3/Chart.min.js -O ${DST}/chart/2.7.3/js/Chart.min.js
Resulting file structure
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">BOOTSTRAP_VER=4.4.1
BOOTSTRAP_ZIP=https://github.com/twbs/bootstrap/archive/v${BOOTSTRAP_VER}.zip
BOOTSTRAP_DST=dashboard/static/vendor/bootstrap/4.4.1
rm -rf install/bootstrap
mkdir -p install/bootstrap
wget -q ${BOOTSTRAP_ZIP} -O install/bootstrap/${BOOTSTRAP_VER}.zip
rm -rf ${BOOTSTRAP_DST}/bootstrap-${BOOTSTRAP_VER}
mkdir -p ${BOOTSTRAP_DST}/
unzip -q install/bootstrap/${BOOTSTRAP_VER} -d install
Examine and study examples
All examples from the getbootstrap.com website are located in install/bootstrap-4.4.1/site/docs/4.4/examples
Copy the css stylesheet
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cp install/bootstrap-4.4.1/site/docs/4.4/examples/dashboard/dashboard.css dashboard/static/site/css/
Copy the javascript file
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cp install/bootstrap-4.4.1/site/docs/4.4/examples/dashboard/dashboard.js dashboard/static/site/js
Copy html file
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="" data-enlighter-language="shell" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">cp install/bootstrap-4.4.1/site/docs/4.4/examples/dashboard/index.html dashboard/templates/site/dashboard.html
After this, we should have the following files in folders:
The dashboard.html template file from the bootstrap examples contains only the required html for the dashboard itself.
What we need to add is the information, where the stylesheets and the javascript files (including bootstrap itself) are located.
The base structure for a template file using bootstrap (or any other UI / layout framework) looks like this:
- starting with a header, specifying meta information and links for the used css files
- following the main part, containing the information display on the website
- end up the the information, where the javascript files are located
The resulting template should look like this
<pre class="EnlighterJSRAW" data-enlighter-group="" data-enlighter-highlight="19-21" data-enlighter-language="generic" data-enlighter-linenumbers="false" data-enlighter-lineoffset="" data-enlighter-theme="" data-enlighter-title="">{% load static %}
<html>
<head>
<title>{% block title %}Home{% endblock title %}</title>
<link rel="icon" type="image/png" href="{% static 'assets/img/favicons/favicon-32x32.png' %}" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" value="en-US" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />
<link href="{% static 'vendor/bootstrap/4.4.1/css/bootstrap.min.css' %}" rel="stylesheet" media="screen" />
<link href="{% static 'site/css/dashboard.css' %}" rel="stylesheet" media="screen" />
<link href="{% static 'site/css/site.css' %}" rel="stylesheet" media="screen" />
</head>
<body>
<main role="main">
<!--
Insert content of dashboard.html here
-->
<div id="site-wrapper">
{% block content %}MISSING CONTENT{% endblock content %}
</div>
</main>
</body>
<script src="{% static 'vendor/popper/2.0.6/js/popper.min.js' %}"></script>
<script src="{% static 'vendor/jquery/3.4.1/js/jquery.min.js' %}"></script>
<script src="{% static 'vendor/jquery/3.4.1/js/jquery.slim.min.js' %}"></script>
<script src="{% static 'vendor/bootstrap/4.4.1/js/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'vendor/chart/2.7.3/js/Chart.min.js' %}"></script>
<script src="{% static 'vendor/feather/4.9.0/js/feather.min.js' %}"></script>
<script src="{% static 'site/js/dashboard.js' %}"></script>
<script src="{% static 'site/js/site.js' %}"></script>
</html>