Overview

Installation

pip install cotidia-admin-tools

Settings

Add the following apps to your settings, before any other app.

INSTALLED_APPS = (
    'admin_tools',
    'admin_tools.menu',
    'admin_tools.dashboard',
    'admin_tools.liststyle',
    ...
)

Administration header theme

Although it is not recommended to amend the less/css from the admin tools panel, it is possible to add exta stylesheet to override the default styles.

We recommend to apply a theme to the header & nav bar to correspond to correspond to the website/client branding.

To do so, add a base_site.html template in your template folder as such:

admin/base_site.html

Here's an example base_site.html:

{% extends "admin/base.html" %}
{% load admin_static %}

{% block custom_css %}
    <link rel="stylesheet" type="text/css" href="{% static "css/admin.theme.css" %}" />
{% endblock %}

{% comment %}
    Please note the following block are not necessary if you pass the following variables via a context processor:

    - AUTHOR
    - AUTHOR_URL
    - SITE_NAME

    As they will be automatically loaded by the base.html template
{% endcomment %}

{# The meta title of the admin #}
{% block meta_site_name %}Website title{% endblock %}

{# The header title above the navigation bar #}
{% block site_name %}Website title{% endblock %}

{# Please note, if you pass 'site_name' in your context processor, you will not need to use those two blocks, as the site_name variable will be used instead #}

{% block author_link %}<a href="http://domain.com">My company</a>{% endblock %}

Note the the admin.theme.css will be your custom stylesheet that will overide any default style.

We recommend to override the header & nav bar using the following LESS code:

@headerBackgroundColor: #c40000;
@headerTextColor: #ffffff;
@headerLinkColor: #ccc;
@headerLinkColorHover: #fff;
@headerNavLinkColor: #fff;
@headerNavLinkColorHover: #fff;
@headerNavLinkColorActive: #fff;


// Normal
.navbar{
    background-color: @headerBackgroundColor;
    border:none;
    color:@headerTextColor;
    border-bottom:1px solid darken(@headerBackgroundColor, 6%);
    //border-top:1px solid #eb0000;
    .nav > li > a{
        color: @headerNavLinkColor;
        &:focus{
            color:@headerNavLinkColor;
        }
        &:hover{
            color:@headerLinkColorHover;
            background-color: darken(@headerBackgroundColor, 4%);
        }
    }
    .navbar-brand {
        font-weight:bold;
        color: @headerNavLinkColor;
        &:hover{
            color:darken(@headerBackgroundColor, 20%);
        }
    }
    .nav > .active > a,
    .nav > .active > a:hover,
    .nav > .active > a:focus {
        color: @headerNavLinkColorActive;
        background-color: darken(@headerBackgroundColor, 6%);
    }
    .nav li.dropdown > .dropdown-toggle .caret {
        border-top-color: @headerTextColor;
        border-bottom-color: @headerTextColor;
    }
}
.navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus, .navbar-default .navbar-nav > .open > a:hover{
    background-color: darken(@headerBackgroundColor, 4%);
    color:#fff;
    .caret{
        border-top-color: #fff;
        border-bottom-color: #fff;
    }
}

Menu

You can generate your custom admin menu by adding some module classes.

First, you will need to create a menu.py file in your project path:

from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from admin_tools.menu import items, Menu

# to activate your custom menu add the following to your settings.py:
#
# ADMIN_TOOLS_MENU = 'my_project.menu.CustomMenu'

class CustomMenu(Menu):
    """
    Custom Menu for test_proj admin site.
    """


    def __init__(self, **kwargs):
        Menu.__init__(self, **kwargs)
        self.children += [
            items.MenuItem(_('Dashboard'), reverse('admin:index')),

            items.MenuItem(_('Custom link'), '/admin/custom-page/'),

            items.ModelList(
                'My section',
                ['app.models.modelName1', 'booking.models.modelName2','booking.models.modelName3','booking.models.modelName4',]
            ),
            items.ModelList(
                'Other section',
                ['booking.models.modelName5',]
            ),
            items.AppList(
                _('Administration'),
                models=('django.contrib.*',)
            ),

            items.Bookmarks()
        ]

    def init_with_context(self, context):
        """
        Use this method if you need to access the request context.
        """
        pass

By default, you will have 4 module options:

  • MenuItem: a link to a specific url of your choice
  • ModelList: a list of models to link to
  • AppList: a list of apps with all their models to link to
  • Bookmarks: a list of custom urls added in the Bookmark model database (no UI for this at the moment)

Once you have created this file, you will need to add it to your settings:

ADMIN_TOOLS_MENU = 'my_project.menu.CustomMenu'

Password reset urls

Add the following urls to your url patterns:

# Password reset features
url(r'^admin/password_reset/$', 'django.contrib.auth.views.password_reset', name='admin_password_reset'),
url(r'^admin/password_reset/done/$', 'django.contrib.auth.views.password_reset_done', name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z]+)-(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm', name="password_reset_confirm"),
url(r'^reset/done/$', 'django.contrib.auth.views.password_reset_complete', name="password_reset_complete"),

Dashboard

You can generate your custom admin dashboard by adding some module classes.

First, you will need to create a dashboard.py file in your project path:

from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse
from admin_tools.dashboard import Dashboard, AppIndexDashboard
from admin_tools.dashboard import modules

class StatsDashboardModule(modules.ModelList):
    title = 'Stats'
    template = 'admin_tools/dashboard/modules/stats.html'
    position = 'left'
    show_title = False

    def init_with_context(self, context):
        request = context['request']
        # we use sessions to store the visited pages stack
        new_entries1 = ModelName1.objects.filter(status__in=['COMPLETE'], submitted=True).count()
        new_entries2 = ModelName2.objects.filter(status__in=['DRAFT'], submitted=True).count()
        new_entries3 = ModelName3.objects.filter(status__in=['ARCHIVE'], submitted=True).count()

        self.children.append(['Completed', new_entries1])
        self.children.append(['Drafts', new_entries2])
        self.children.append(['Archives', new_entries3])

class CustomIndexDashboard(Dashboard):
    """
    Custom index dashboard for test_proj.
    """
    def __init__(self, **kwargs):
        Dashboard.__init__(self, **kwargs)

        # append a link list module for "quick links"
        self.children.append(modules.LinkList(
            _('Quick links'),
            layout='inline',
            draggable=False,
            deletable=False,
            collapsible=False,
            children=[
                [_('<i class="icon-plus"></i> Return to site'), '/', 'action'],
                [_('<i class="icon-edit"></i> Change password'), reverse('admin:password_change'), 'action'],
                [_('Log out'), reverse('admin:logout'), 'action'],
            ],
            position = 'right'
        ))

        self.children.append(StatsDashboardModule(
            _('Statistics'),
            position = 'left'
        ))


        # append a recent actions module
        self.children.append(
             modules.RecentActions(_('Recent Actions'), 10, position = 'right'),

        )

    def init_with_context(self, context):
        """
        Use this method if you need to access the request context.
        """
        pass

By default, you will have 4 module options:

  • LinkList: a list of custom links
  • AppList: a list of apps with all their models to link to
  • ModelList: a list of models to link to
  • RecentActions: all the recent actions from the Django admin log
  • Feed: a link to a feed to display on the dashboard

The position attributes indicate on which side of the dashboard you would like the module to appear. Left being the main area and right being the side bar.

Once you have created this file, you will need to add it to your settings:

ADMIN_TOOLS_MENU = 'my_project.menu.CustomMenu'

You can create custom module by extending one of those modules and assigning a custom template, as you can see in this demo code with StatsDashboardModule.

Django compatibility

Django Admin tools
1.4.1 0.4.1
1.5 0.5

Translations

Admin tools implements custom templates for Django-rosetta.

Django-rosetta doesn't get installed by default so you will have to install to make use of it.

In menus.py, you can create a link to translation using the following code:

items.MenuItem(_('Translations'), reverse('rosetta-pick-file')),

A short guide for managing translations

Within the settings.py add the template directory to the varible LOCAL_PATHS:

LOCALE_PATHS = ( os.path.join(PROJECT_PATH, "../locale"), )

To make and compile the language file:

  1. Go to the project directory and create a folder called "locale"

  2. cd to the project dir

  3. run the following command line for each language, you can include the "-i" to ignore any directories you don't want (e.g. admin directory):

    django-admin.py makemessages -l en -i "templates/admin" -i "templates/admin-desti" -i "templates/registration" -i "templates/reversion"

  4. After you have made each language file, compile it by inserting this commland line in Terminal

    django-admin.py compilemessages