Улучшаем админку

Одно из слабых мест джанго-админки - главная страница. Идея авто-группировки моделей по приложениям и вывод столбиком в одну колонку работает только на начальных этапах, дальше это становится просто неудобно - куча лишней информации и довольно сложные пути для того, чтобы добавить полезную. Ну, например, чтобы названия приложений писались русскими буквами - полностью перекрывать шаблон.

И тут на помощь приходит django-admin-tools. С этим приложением минут за 20 можно получить "приборную панель" с произвольной группировкой приложений/моделей, вкладками, любым числом колонок, различными блоками, которые каждый пользователь сможет расставить, как ему удобнее, скрывать и сворачивать по желанию, закладками, настраиваемым меню и удобным способом добавления во все это хозяйство всего, чего только можно придумать.

Вот так, например, сейчас выглядит админка к сайту НадоВместе :

http://kmike.ru/img/habr/admin/small.png

(это только часть, вот скриншот целиком)

Разберемся поподробнее.

Установка

  1. pip install -e hg+http://bitbucket.org/izi/django-admin-tools/#egg=django-admin-tools

    Ставим дев-версию, т.к. там много новых вкусных штук: например, упрощен API и добавлены группы. Если не установлен mercurial, то можно скачать последнюю ревизию архивом , распаковать и запустить python setup.py install.

  2. Добавляем admin_tools в INSTALLED_APPS (обязательно до django.contrib.admin):

    INSTALLED_APPS = (
        'admin_tools',
        'admin_tools.theming',
        'admin_tools.menu',
        'admin_tools.dashboard',
        # ...
        'django.contrib.auth',
        'django.contrib.sites',
        'django.contrib.admin'
        # ... и другие приложения ...
    )
    
  3. python manage.py syncdb

  4. подключаем в urls.py:

    urlpatterns = patterns('',
        url(r'^admin_tools/', include('admin_tools.urls')),
        #... и т.д. ...
    )
    
  5. копируем медиа-файлы (js, css и картинки) в MEDIA_ROOT проекта.

Все, можно зайти в админку и удивиться тому, как все поменялось. Установка, как видите, вполне обычная, никаких джанговских файлов заменять не нужно (как в grappelli было когда-то).

Блоки

Самая полезная штука в django-admin-tools - это, конечно, блоки. Вы можете настроить, какие блоки и как показывать на заглавной странице, писать свои блоки и брать готовые.

  1. Создаем заготовку для "приборной панели":

    python manage.py customdashboard
    

    После этого в корне проекта появится файл dashboard.py с заготовкой. Можно его, в принципе, и руками написать.

    В файле будет содержаться 2 класса: CustomIndexDashboard и CustomAppIndexDashboard - для главной страницы админки и страницы отдельного приложения. Нас тут будет интересовать класс CustomIndexDashboard.

  2. Указываем в settings.py, что будем использовать свою "приборную панель" на заглавной странице админки:

    ADMIN_TOOLS_INDEX_DASHBOARD = 'yourproject.dashboard.CustomIndexDashboard'
    
  3. Для примера: объединим в одном блоке стандартные джанговские модели из auth и свои данные о профайлах, назвав при этом блок по-русски:

    from admin_tools.dashboard import modules, Dashboard
    
    class CustomIndexDashboard(Dashboard):
    
       def __init__(self, **kwargs):
           Dashboard.__init__(self, **kwargs)
           self.children.append(
               modules.ModelList(
                   title = u'Пользователи',
                   models=(
                       'django.contrib.auth.*',
                       'my_accounts.models.Profile',
                   ),
               )
           )
    

    В списке моделей указываются полные пути к моделям, которые требуется подключить. Все модели, которые перечислены в models, должны быть зарегистрированы в джанговской админке как обычно. Если моделей несколько, то можно их все не перечислять, т.к. есть поддержка *. Если вы включили кучу моделей через * и нужно из них убрать несколько, то есть симметричный параметру models параметр exclude со списком моделей, которые показывать не нужно (там тоже есть поддержка *).

Стандартные блоки

django-admin-tools включает в стандартную поставку несколько готовых блоков для приборной панели. Детальную информацию о них можно найти в документации. Тут будет просто краткий обзор + описание замечательного modules.Group, которого не было в документации на момент написания статьи.

Импортировать их следует так: from admin_tools.dashboard import modules

  1. modules.ModelList - как мне кажется, это самый основной и полезный блок. Позволяет группировать произвольные модели в рамках одного блока.

    http://kmike.ru/img/habr/admin/model-list.png
  2. modules.Group - еще один супер-полезный блок. Позволяет группировать любые другие блоки внутри себя. Блоки могут или располагаться друг над другом, или в виде "аккордеона", или во вкладках. Очень удобно, например, для графиков, или для отделения основных и часто используемых разделов от побочных.

    http://kmike.ru/img/habr/admin/group.png

    Пример использования:

    self.children.append(modules.Group(
        title=u"Статистика",
        display="tabs",
        children=[
            nadovmeste_modules.Overview(),
            nadovmeste_modules.Subscribers(),
            nadovmeste_modules.Finances(),
            nadovmeste_modules.Users(),
        ]
    ))
    

    В списке children можно указывать любые другие блоки, в.т.ч. разных типов. В примере тут не стандартные модули из admin_tools.dashboard.modules, а свои (о том, как их делать - позже).

    Поддержки вложенных групп пока нет (а если точнее, то сейчас js при этом работает неправильно).

  3. modules.LinkList - список произвольных ссылок. Внешние ссылки могут помечаться специальной иконкой, ссылки могут располагаться как горизонтально, так и в столбик.

    http://kmike.ru/img/habr/admin/link-list.png
  4. modules.AppList - по сути, аналог главной страницы стандартной джанговской админки. Список приложений и моделей в них. Скажу по секрету, тут есть еще не документированный параметр models, который абсолютно аналогичен этому параметру в modules.ModelList - с той разницей, что потом модели будут сгруппированы по приложениям. Этот блок полезен, если хочется добавить все по-быстрому, или повторить обычную джанговскую админку - в остальных случаях, как мне кажется, лучше подходит ModelList. Хотя может это дело вкуса.

  5. modules.RecentActions - список последних действий, как в стандартной джанговской админке. Не знаю, зачем он нужен :)

  6. modules.Feed - позволяет показывать ленты RSS в админке.

Пишем свои блоки

Напишем, например, абсолютно бесполезный блок, который будет просто выводить какое-то сообщение, переданное ему в конструкторе.

  1. Наследуемся от admin_tools.dashboard.modules.DashboardModule:

    class MyModule(modules.DashboardModule):
        def is_empty(self):
            return self.message == ''
    
        def __init__(self, **kwargs):
            super(MyModule, self).__init__(**kwargs)
            self.template = 'my_blocks/hello.html'
            self.message = kwargs.get('message', '')
    
  2. Делаем шаблон templates/my_blocks/hello.html

    {% extends "admin_tools/dashboard/module.html" %}
    {% block module_content %}
        <h4>{{ module.message  }}</h4>
    {% endblock %}
    

    Как видите, объект модуля передается в шаблон. Это означает, что можно передавать любые данные через его атрибуты (что мы и сделали в примере с message).

  3. Подключаем блок в dashboard.py

    self.children += [MyModule(title=u"Приветствие", message = u'Привет!')]
    

Все, готово. Думаю, теперь понятно, как делать любые более сложные штуки, рисовать в блоках графики и тд. Готовим данные, делаем шаблон. Если в контексте шаблона нужен request, то переопределяйте метод init_with_context.

Полученный блок можно будет таскать мышкой, сворачивать-разворачивать, располагать отдельно или во вкладке у modules.Group и тд. - наравне со стандартными блоками.

Да, еще, если нужно что-то просто дописать сверху или снизу стандартного блока, то можно свой блок/шаблон не делать, а воспользоваться атрибутами модуля pre_content и post_content.

Внешний вид

Люди достаточно осторожно подошли к дизайнерству, и новые элементы смотрятся вполне органично рядом со стандартными джанговскими. Но если вам тоже не нравится ненужный заголовок и стандартная шапка из django-admin-tools, то их проще всего убрать с помощью css. Хорошо бы еще логотип в шапку добавить. Заодно и с тем, как делать темы, разберемся.

http://kmike.ru/img/habr/admin/head.png
  1. Делаем css-файл со своей темой. Для примера можно посмотреть тему, которая используется в нашей админке, еще пример есть в стандартной поставке.

  2. Подключаем файл с темой: в settings.py добавляем настройку

    # путь относительно MEDIA_ROOT
    ADMIN_TOOLS_THEMING_CSS = 'css/theming.css'
    

Что дальше

В статье нет ничего про меню, закладки, настройку собственно приборных панелей, про панели для отдельных приложений. Обо всем этом можно почитать в документации. Если хотите помочь проекту, подключившись к разработке - welcome. Если что не работает в django-admin-tools, то это я все сломал, если что-то сделано круто - напишите весточку David Jean Louis.

Небольшие хитрости

Если вы обновили модули в своей приборной панели (добавили, удалили, поменяли местами), и после этого все куда-то уехало, то удалите записи из DashboardPreferences.

Статистика на скриншоте - с тестового сервера, реальные данные nadovmeste.ru не "спалил".

Warning

Описание относится к django 1.1 и django-admin-tools 0.4, оно могло устареть. Читайте официальную документацию!