Pull to refresh

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

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

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

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

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

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

Установка


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 проекта. Что-то вроде этого — вы ведь используете virtualenv?

cp -r /home/kmike/envs/nadovmeste/src/django-admin-tools/admin_tools/media/admin_tools /path/to/yourproject/media/

Можно вместо копирования сделать симлинк или использовать django-static-files.

Все, можно зайти в админку и удивиться страшной пятнистой шапке тому, как все поменялось. Установка, как видите, вполне обычная, никаких джанговских файлов заменять не нужно (как в 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 — как мне кажется, это самый основной и полезный блок. Позволяет группировать произвольные модели в рамках одного блока.

image

2. modules.Group — еще один супер-полезный блок. Позволяет группировать любые другие блоки внутри себя. Блоки могут или располагаться друг над другом, или в виде «аккордеона», или во вкладках. Очень удобно, например, для графиков, или для отделения основных и часто используемых разделов от побочных.

image

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

        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 — список произвольных ссылок. Внешние ссылки могут помечаться специальной иконкой, ссылки могут располагаться как горизонтально, так и в столбик.

image

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.append(MyModule(title=u"Приветствие", message = u'Привет!'))


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

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

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

Внешний вид


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

1. Делаем css-файл со своей темой. Для примера можно посмотреть тему, которая используется в нашей админке, еще пример есть в стандартной поставке.

2. Подключаем файл с темой: в settings.py добавляем настройку
ADMIN_TOOLS_THEMING_CSS = 'css/theming.css' # путь относительно MEDIA_ROOT


Что дальше


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

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


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

Статистика на скриншоте — с тестового сервера, реальные данные nadovmeste.ru не «спалил». Если интересно, то в следующей статье расскажу, как заполнять базу большим количеством тестовых данных, и как строк за 5 кода (включая шаблон) получать любые графики со статистикой (как, например, на скриншоте — график со статистикой регистраций пользователей по дням).

Да, спасибо obiwanus и leoglu за ценные замечания на этапе подготовки статьи.
Tags:
Hubs:
+95
Comments 45
Comments Comments 45

Articles