Download
Please note that the sample project does not include the Metronic Tailwind CSS source files by default. To integrate the styles, you need to copy the Metronic Tailwind CSS source files from your downloaded Metronic folder.
Clone Integration Repository
git clone https://github.com/keenthemes/metronic-tailwind-html-integration.git
cd metronic-tailwind-html-integration/metronic-tailwind-django
Copy Assets Folder
assets
folder from the
metronic-tailwind-html/dist
directory into your Django project
static/
directory. The resulting directory structure should look like this:
static/assets/
.
Setup Virtual Environment
# Create virtual environment
python -m venv venv
# Activate virtual environment
# On macOS/Linux:
source venv/bin/activate
# On Windows:
venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
Run Database Migrations
# Run database migrations
python manage.py migrate
# Create a superuser (optional)
python manage.py createsuperuser
# Collect static files
python manage.py collectstatic --noinput
Start Development Server
# Start the development server
python manage.py runserver
# Or specify host and port
python manage.py runserver 0.0.0.0:8000
http://127.0.0.1:8000
to see your Django app in action. You can explore both demo layouts:
# Demo 1 - Sidebar Layout
http://127.0.0.1:8000/demo1/
# Demo 2 - Header Layout
http://127.0.0.1:8000/demo2/
# Admin Interface
http://127.0.0.1:8000/admin/
If you prefer to create a project from scratch, follow the manual setup steps in the next section.
Create Django Project
This guide assumes you have Python 3.10+ installed. For a ready-to-use Django project, you can download our pre-configured example from the Download section.
Prerequisites & Environment Setup
# Check Python version (3.10+ required)
python --version
# Create project directory
mkdir my-metronic-django
cd my-metronic-django
# Create virtual environment
python -m venv venv
# Activate virtual environment
# On macOS/Linux:
source venv/bin/activate
# On Windows:
venv\Scripts\activate
# Upgrade pip
pip install --upgrade pip
Install Django & Dependencies
# Install core dependencies
pip install Django>=5.1.0
pip install whitenoise # For static file serving
pip install pytest-django # For testing
# Create requirements.txt
pip freeze > requirements.txt
Create Django Project Structure
# Create Django project
django-admin startproject metronic_project .
# Create apps directory for better organization
mkdir apps
touch apps/__init__.py
# Create directory structure
mkdir -p templates/partials
mkdir -p static/{src,dist,public}
mkdir -p tests
Configure Split Settings
# Create settings directory
mkdir metronic_project/settings
touch metronic_project/settings/__init__.py
# Move and split settings
mv metronic_project/settings.py metronic_project/settings/base.py
metronic_project/settings/__init__.py
:
import os
# Default to development settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'metronic_project.settings.development')
Configure Base Settings
metronic_project/settings/base.py
with Django 5.1 configuration:
from pathlib import Path
import sys
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Add apps directory to Python path
sys.path.insert(0, str(BASE_DIR / 'apps'))
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "your-secret-key-here"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
DJANGO_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
]
LOCAL_APPS = [
# Will add demo apps here
]
INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"whitenoise.middleware.WhiteNoiseMiddleware", # For static files
"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 = "metronic_project.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [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",
],
},
},
]
WSGI_APPLICATION = "metronic_project.wsgi.application"
# Database
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Internationalization
LANGUAGE_CODE = "en-us"
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
STATIC_URL = "/static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
STATICFILES_DIRS = [
BASE_DIR / "static" / "dist",
BASE_DIR / "static" / "public",
]
# STORAGES setting for Django 5.1
STORAGES = {
"default": {
"BACKEND": "django.core.files.storage.FileSystemStorage",
},
"staticfiles": {
"BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
},
}
# Default primary key field type
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
Create Development Settings
metronic_project/settings/development.py
:
from .base import *
# Development-specific settings
DEBUG = True
ALLOWED_HOSTS = ['localhost', '127.0.0.1', '0.0.0.0']
# Development database
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Debug toolbar (optional)
# INSTALLED_APPS += ['debug_toolbar']
# MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
Create Production Settings
metronic_project/settings/production.py
:
import os
from .base import *
# Production-specific settings
DEBUG = False
ALLOWED_HOSTS = os.environ.get('ALLOWED_HOSTS', '').split(',')
# Security settings
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_SECONDS = 31536000
SECURE_REDIRECT_EXEMPT = []
SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Database configuration for production
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ.get('DB_NAME'),
"USER": os.environ.get('DB_USER'),
"PASSWORD": os.environ.get('DB_PASSWORD'),
"HOST": os.environ.get('DB_HOST', 'localhost'),
"PORT": os.environ.get('DB_PORT', '5432'),
}
}
Test Project Setup
# Check for configuration issues
python manage.py check
# Run initial migration
python manage.py migrate
# Test the development server
python manage.py runserver
http://127.0.0.1:8000
. Your Django project foundation is now ready for Metronic integration!
Integrate Core
This section assumes you have completed the "Create Django Project" steps. We'll be creating minimal Django apps focused on demonstrating Metronic layouts with hardcoded data.
Create Django Apps
# Create demo1 app (sidebar layout)
python manage.py startapp demo1 apps/demo1
# Create demo2 app (header layout)
python manage.py startapp demo2 apps/demo2
Update Settings with Apps
metronic_project/settings/base.py
:
# Update LOCAL_APPS in base.py
LOCAL_APPS = [
"demo1",
"demo2",
]
Configure Main URLs
metronic_project/urls.py
to include app URLs and serve static assets:
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from django.views.generic import RedirectView
urlpatterns = [
path('admin/', admin.site.urls),
path('demo1/', include('demo1.urls')),
path('demo2/', include('demo2.urls')),
path('', RedirectView.as_view(url='/demo1/', permanent=False)),
]
# Serve static files during development
if settings.DEBUG:
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
# Add alias for assets/ to serve static files at /assets/ path
urlpatterns += static('/assets/', document_root=settings.BASE_DIR / 'static')
Create Django Views
apps/demo1/views.py
for the sidebar layout:
from django.views.generic import TemplateView
from typing import Dict, Any
class IndexView(TemplateView):
"""Main dashboard view for demo1 with sidebar layout."""
template_name = 'demo1/index.html'
def get_context_data(self, **kwargs) -> Dict[str, Any]:
context = super().get_context_data(**kwargs)
# Add your hardcoded dashboard data here
context.update({
'page_title': 'Dashboard',
'page_description': 'Central Hub for Personal Customization',
# Add stats, activities, projects data...
})
return context
apps/demo2/views.py
for the header layout following the same pattern.
For complete view examples with extensive hardcoded sample data, refer to the actual project files:
metronic-tailwind-django/apps/demo1/views.py
and
metronic-tailwind-django/apps/demo2/views.py
in the downloaded integration package.
Create URL Configurations
apps/demo1/urls.py
:
from django.urls import path
from . import views
app_name = 'demo1'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
apps/demo2/urls.py
:
from django.urls import path
from . import views
app_name = 'demo2'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
Test Core Integration
# Start the development server
python manage.py runserver
# Test the URLs (in another terminal or browser)
curl -I http://127.0.0.1:8000/demo1/
curl -I http://127.0.0.1:8000/demo2/
Integrate Styles
This section assumes you have completed the "Create Django Project" and "Integrate Core" steps. Make sure you have the Metronic HTML files available for copying assets and templates.
Copy Metronic Assets
# Navigate to your Django project root
cd my-metronic-django
# Copy assets from Metronic HTML package
# Replace /path/to/metronic-tailwind-html with your actual path
cp -r /path/to/metronic-tailwind-html/dist/assets static/
# Verify the assets are copied
ls -la static/assets/
# You should see directories like:
# css/, js/, media/, plugins/, etc.
Create Base Template Partials
templates/partials/head.html
with Django static file loading:
{% raw %}{% load static %}
<meta charset="utf-8"/>
<title>
{% block title %}{{ page_title|default:"Dashboard" }}{% endblock %} | Metronic
</title>
<meta admin="" content="{{ page_description|default:" dashboard"="" metronic="" name="description" }}"=""/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<!--begin::Fonts(mandatory for all pages)-->
<link href="https://fonts.googleapis.com/css?family=Inter:300,400,500,600,700" rel="stylesheet"/>
<!--end::Fonts-->
<!--begin::Vendor Stylesheets(used for this page only)-->
{% block vendor_css %}{% endblock %}
<!--end::Vendor Stylesheets-->
<!--begin::Global Stylesheets Bundle(mandatory for all pages)-->
<link href="{% static 'assets/plugins/global/plugins.bundle.css' %}" rel="stylesheet" type="text/css"/>
<link href="{% static 'assets/css/style.bundle.css' %}" rel="stylesheet" type="text/css"/>
<!--end::Global Stylesheets Bundle-->
<!--begin::Custom Stylesheets(optional)-->
{% block custom_css %}{% endblock %}
<!--end::Custom Stylesheets-->
{% endraw %}
templates/partials/scripts.html
and
templates/partials/theme-mode.html
following the same pattern.
Convert Metronic HTML to Django Templates
metronic-tailwind-html/dist/demo1/index.html
• Create
templates/demo1/base.html
using the main layout structure
• Extract header, sidebar, and footer into partials:
templates/demo1/partials/
• Create
templates/demo1/index.html
with the dashboard content
• Replace static paths with
{% static 'assets/...' %}
• Add Django template blocks:
{% block content %}
,
{% block title %}
, etc.
metronic-tailwind-html/dist/demo2/index.html
• Follow the same conversion process as Demo1 but for header layout
• Create corresponding partials and templates in
templates/demo2/
Key Django Template Conversions
{% raw %}
<!-- 1. Add Django template loading at the top -->
{% load static %}
{% extends "demo1/base.html" %}
<!-- 2. Convert static asset paths -->
<!-- FROM: src="assets/media/logos/logo.svg" -->
<!-- TO: -->
src="{% static 'assets/media/logos/logo.svg' %}"
<!-- 3. Add Django template blocks -->
{% block title %}{{ page_title }}{% endblock %}
{% block content %}
<!-- Your page content here -->
{% endblock %}
<!-- 4. Use Django context variables -->
<!-- FROM: <h1>Dashboard</h1> -->
<!-- TO: -->
<h1>
{{ page_title|default:"Dashboard" }}
</h1>
<!-- 5. Loop through Django context data -->
{% for stat in stats %}
<div class="stat-card">
{{ stat.title }}: {{ stat.value }}
</div>
{% endfor %}{% endraw %}
Configure Static Files Collection
# Collect static files for production
python manage.py collectstatic --noinput
# Verify static files are working
python manage.py runserver
# Test static file access in browser:
# http://127.0.0.1:8000/static/assets/css/style.bundle.css
# http://127.0.0.1:8000/static/assets/js/scripts.bundle.js
Test Complete Integration
# Start the development server
python manage.py runserver
# Test both layouts:
# http://127.0.0.1:8000/demo1/ (Sidebar layout)
# http://127.0.0.1:8000/demo2/ (Header layout)
# Check browser console for any JavaScript errors
# Verify all CSS and JS files are loading correctly