Metronic Admin Dashboard with Django

I was searching for an admin dashboard with AngularJS support for a web application to provide stats / charts, metrics and forms in a suitable and visual way. I had a look into several dashboard themes, which are available and decided on Metronic (affiliate link). Click here to see the demo.

With the package bought, I got the theme in plain HTML with JavaScript / jQuery and an AngularJS version. But as I use Django for my projects and no Django module was provided, I had to do some changes to get it working. For those of you wondering why I’m writing this article in English: I searched for already existing tutorials on how to get Metronic working in Django, I stumbled across many requests and questions but not on a single answer. As all of them were in English, I decided to use that language so more readers can take advantage of this post.

First of all, I assume you already set up a Django project and created a virtual environment to work in. If you didn’t, please find more information here:


In your Django app directory, activate the virtual environment with virtualenv\Scripts\activate (Windows) or source virtualenv/bin/activate (Linux). Then create a new Django app with python manage.py startapp metronic which will contain all the static files and logic which we will need to get Metronic up and running. Next, make a static folder inside the metronic directory which was created while executing the last command. Inside the static folder, create another folder and name it „metronic“. This helps to avoid conflicts with other files which might have the same name.

Putting the Metronic files into the right place

When done, you have to copy a lot of files from the Metronic archive you downloaded after you purchased:

copy theme\templates\<themename>\angularjs\js\* --> static\metronic\js\
copy theme\templates\<themename>\angularjs\tpl\* --> static\metronic\tpl\
copy theme\templates\<themename>\angularjs\views\* --> static\metronic\views\

copy theme\assets\* --> static\metronic\

Please not, that some of the processes might take some time, as several thousand files have to be copied. After that, create a folder named „templates“ on the same level as the static directory and copy theme\templates\admin2\angularjs\index.html into it. I would recommend to rename to index.html file to something like metronic_index.html to avoid conflicts with other modules.

You should now have a directory structure similar to this:

|   \---metronic
|       +---admin
|       |   +---layout
|       |   |   +---css
|       |   |   |   \---themes
|       |   |   +---img
|       |   |   \---scripts
|       |   +---layout2 (similar to layout)
|       |   +---layout3 (similar to layout)
|       |   +---layout4 (similar to layout)
|       |   \---pages
|       |       +---css
|       |       +---img
|       |       +---media
|       |       \---scripts
|       +---frontend
|       |   +---layout
|       |   |   +---css
|       |   |   +---img
|       |   |   \---scripts
|       |   +---onepage
|       |   |   +---css
|       |   |   +---img
|       |   |   \---scripts
|       |   \---pages
|       |       +---css
|       |       +---img
|       |       \---scripts
|       +---global
|       +---js
|       |   +---controllers
|       |   \---scripts
|       +---tpl
|       \---views
|           +---datatables
|           \---profile

Replacement of dynamic paths in Metronic code

In the next steps, we have to do some massive find/replace actions as we won’t get far with the dynamic path used in the html, javascript and css files. I used PyCharm for that which provides an excellent find/replace tool which is able to use regular expressions and executes recursively through the folder hierarchy. Notepad++ might be of help as well.

The following replacements have to be executed. If you need more explanation or help on them, please drop me a comment:

  1. replace „(..\/..\/..\/assets)([\.\/\w\d-_]*)“ with „{% static ‚metronic$2‘ %}“ in all css, js and html files
  2. replace Metronic.setAssetsPath(‚../../../assets/‘); with Metronic.setAssetsPath(‚{% static ‚metronic/‘ %}‘);
  3. replace „‚(\w+\/[\w\.-]*)'“ with „‚{% static ‚metronic/$1‘ %}'“
  4. replace ‚../../../assets/ with ‚/static/metronic/
  5. replace ‚js/ with ‚/static/metronic/js/
  6. replace views/ with /static/metronic/views/
  7. replace ‚js/ with ‚/static/metronic/js/

As some html is not served through Django, the {% static … %} tag won’t work. Therefore, we have to replace some changes again, we just made:

  1. replace „\{% static ‚metronic([\/\w\d\.-]*)‘ %}“ with „/static/metronic$1“  for static/metronic/tpl/*
  2. replace „\{% static ‚metronic([\/\w\d\.-]*)‘ %}“ with „/static/metronic$1“  for static/metronic/views/*
  3. replace „\{% static ‚metronic([\/\w\d\.-_]*)‘ %}“ with „/static/metronic$1“  for static/metronic/*

Making Metronic available through Django

After that, you should create a new view to have Django deliver the html file. Here is an example how the views.py could look like:

from django.views.generic import TemplateView

class MetronicAdmin(TemplateView):
    template_name = 'metronic_index.html'

Now, you just need to add an url pattern into the main urls.py:

from django.conf.urls import patterns, url
from metronic.views import MetronicAdmin

urlpatterns = patterns(
    url(r'^/', MetronicAdmin.as_view(), name='metronicadmin'),

After that, you should be able to run the Django runserver command and see your Metronic under

If you have any questions or remarks, please drop me a comment.

Torsten Feld :

View Comments (5)

  • Hi there, when i added the urls.py line of code, i keep getting the following:

    Using the URLconf defined in django_project.urls, Django tried these URL patterns, in this order:

    ^/ [name='metronicadmin']

    The current URL, , didn't match any of these.

  • Hi there, when i added the urls.py line of code, i keep getting the following:

    Using the URLconf defined in django_project.urls, Django tried these URL patterns, in this order:

    ^/ [name='metronicadmin']

    The current URL, , didn't match any of these.

    • Hi Dominik,

      thanks you for your question!
      Could you put your view, urls.py and the URL you opened in a gist or pastebin? That would make it easier for me to get the full picture.

  • Great job Torsten!

    You have one error in your guide:
    7. replace 'js/ with '/static/metronic/js/

    Which should be
    7. replace "js/ with "/static/metronic/js/

    This two files will produce "constant loop on loading"
    "GET /js/app.js HTTP/1.1" 200 8993
    "GET /js/directives.js HTTP/1.1" 200 8993

    With regard to the pattern - the problem is the same as for Dominik even with
    APPEND_SLASH = true


This website uses cookies.