Django-admin в качестве интерфейса: Путь в капкан

Знакомство с django-admin поражает воображение. Непосредственно на основе моделей базы данных  вы получаете готовый веб-интерфейс. Этот интерфейс будет иметь фильтры поиска, учитывать условия для полей, подключать справочники связанных объектов. Далее, просто добавляя «подсказки» для моделей базы, вы сможете сделать интерфейс еще удобнее с минимальными трудозатратами.

В общем, возникает вполне естественное желание использовать всю эту навороченную систему для того, чтобы построить пользовательский интерфейс (автоматизированное рабочее место).

Так я и поступил — и это оказался путь в капкан. Если хватит задора на серию статей, то дальше расскажу о том, как из него выбраться, прихватив с собой кусочек сыра :)

В начале все идет просто замечательно. Ну разве могут не радовать такие возможности:

booking/admin.py

from django.contrib import admin
from booking.models import Sale

class SaleAdmin(admin.ModelAdmin):

    ## Настройка табличного просмотра
    # поля для табличного просмотра
    list_display = ('docid', 'date', 'doctype', 'customer', 'amount', 'manager',)
    # поля для полнотекстового поиска
    search_fields = ('docid', 'customer',)
    # поля, актуальные значения которых будут
    # выведены в боковой колонке и позволят фильтровать список
    list_filter = ('doctype', 'manager',)
    # поля, недоступные для изменения
    # поле, по которому будет доступна навигация по иерархическому календарю
    date_hierarchy = 'date'

    ## Настройка формы редактирования
    # поля, защищенные от записи
    readonly_fields = ('inserted', 'inserted_by', 'id', 'manager',)
    # поля, которые не надо показывать
    exclude = ('something')
    # группировка полей по "строкам" формы для лучшего восприятия
    fieldsets = (
        (None, {
            'fields': (
                (
                    'agency',
                    'docid',
                    'doctype',
                ),(
                    'date',
                ),(
                ),(
                    'fare',
                    'comission',
                ),(
                    'amount',
                ),(
                    'comments',
                ),(
                    'manager',
                    'inserted',
                    'inserted_by',
                ),)}),
        )       

    # из этой формы будет позаимствован метод clean()
    form = SaleForm

    # дополнительный css
    class Media:
        css = {
            'all': ("/media/css/admin_form.css",)
        }

admin.site.register(Sale, SaleAdmin)

Описываем, наслаждаемся. Фильтры, интерактивные календарики, дропдаун и красивая зеленая кнопочка «+», дающая возможность на ходу зарегистрировать продажу…

Получается примерно так (при том, что мы не написали ни строки кода для дизайна, отображения, сохранения и проверки полей, а все работает — ну разве не лапочка?):

django-admin-form

И вы «бесплатно» получите не только эту форму, но и табличный просмотр с указанными фильтрами, соответственно.

Вот только даты в табличном просмотре почему-то выводятся как «15 Март 2012», а не ‘15.03.2012’, ну это мы сейчас поправим… так, документация…, google…, vi /usr/lib/pymodules/python2.5/django/contrib/admin/…, google… упс!

При включенной locale формат даты задан жестко только ей и ни на какие настройки не реагирует.

Есть workaround:

from django.utils.translation import ugettext as _
class SaleAdmin(admin.ModelAdmin):
    ...
    list_display = (...,'format_date',...)

    def format_date(self, obj):
        return obj.date.strftime('%d.%m.%Y')
    format_date.short_description = _("Date")
    format_date.admin_order_field = 'date'

Ну… выкрутились. Особенно приятно, когда у вас не одна, а три даты в списке ;)

Поздравляем себя с маленькой победой и идем показывать клиенту.
Клиент добрый и изо всех сил делает вид, что понимает, что смотрит на черновой вариант… вот только как бы разделить разряды в колонке суммы?

Конечно! Мы же уже умеем это решать! Уходим и делаем знакомым манером. По ходу понимаем, что, «к клиенту не ходи» — а цифирки надо бы еще выровнять вправо… так, документация…, google…, vi /usr/lib/pymodules/python2.5/django/contrib/admin/…, google… упс!

Не выправить.
С числами вообще мало что можно выправить, поскольку их обработка вшита в код django-admin.

А подбивать итог?

О! Нашли django-reporting! (ему будет посвящена отдельная заметка).
Только вот беда… из него можно попасть в редактирование записи, а обратно выход — в стандартный change-list.

А как бы нам теперь сделать отрицательные числа красненькими?

А как бы нам тут же рисовать остаток по счету?

А как бы нам вставить свои ссылочки туда, где «Добро пожаловать» и «Выход»?

А как бы нам сделать русскими названия модулей на главной странице?

А как нам быть с тем, что клиент вообще не понимает, чего ему делать, глядя на главную страницу, в том дизайне, который у нее автогенерится по-умолчанию?

Наверное, на некоторые из этих вопросов есть более-менее годные ответы, некоторые решаются правкой дефолтных шаблонов (скопированных в свой /templates/admin).

Но, в итоге, получается довольно дурацкая ситуация: программист, начинающий использовать Django с неизбежностью познакомится с django-admin и захочет использовать его для построения интерфейса. И, в результате…

  • Либо он добьется результата затратив не меньше усилий, чем на написание собственного интерфейса (потому что Django и без django-admin неплох). В результате он обречет себя на постоянное преодоление условностей django-admin и сильно ограничит свои возможности делать «произвольный» интерфейс по мере необходимости.
  • Либо он потеряет время на то, чтобы понять бесперспективность этого подхода и будет искать иной каркас приложения или создавать свой.

Я пошел по второму пути, но по дороге прихватил некоторые «вкусности» django-admin, такие как базовый шаблон, форму редактирования (change_form) с разбивкой по полям на основе adminform и табличный список (change_list) с группировкой и подитогами на основе django-reporting. Большинство этих компонентов претерпели некоторые изменения и в результате получился довольно забавный велосипед.

О том, как собрать такой же и как поехать на нем, я расскажу в следующих статьях этого цикла.

Мои выводы

  • django-admin нужно осваивать и использовать. Он позволяет действительно быстро делать те вещи, которые нужны только вам и позволит сэкономить массу времени.
  • Использовать django-admin для создания пользовательского интерфейса — тупиковый путь.
  • Самое печальное в том, что преодоление трудностей на этом пути не сделает счастливым вашего клиента — потому что результатом будет все равно технически-ориентированный интерфейс, как это удобно программисту, а не проблемно-ориентированный интерфейс, которого ожидает клиент.

P.S.

Статья год пролежала на полке. Вышел новый Django, может чего и изменилось к лучшему.

Python/Django, Разработка

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

captcha

Please enter the CAPTCHA text