Главная | Архив новостей | Общение | Площадка | Примеры OpenID
Хостинг Django от «Джино»
Оглавление

Собственные классы ModelAdmin

Изменения, которые мы сделали ранее — null=True, blank=True и verbose_name — являются изменениями на уровне модели, а не на уровне интерфейса администратора. То есть, эти изменения являются фундаментальной частью модели, интерфейс администратора Django просто использует их, и в них ничего специфического для административного интерфейса нет.

Помимо этого, интерфейс администратора предоставляет множество возможностей настроить его работу для конкретной модели. Эти настройки реализуются с помощью классов ModelAdmin.

Настройка списка редактирования

Давайте погрузимся в настройку интерфейса, определив поля, которые будут отображатся в списке редактирования для нашей модели Author. По-умолчанию, в списке изменения отображается результат выполнения метода __unicode__() для каждого объекта модели. В главе «Модели» мы определили метод __unicode__() для модели Author так, чтобы он возвращал имя и фамилию:

class Author(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=40)
    email = models.EmailField(blank=True, verbose_name='e-mail')

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)

В результате список изменения обьектов Author отображает имя и фамилию вместе, вы можете это увидеть на рисунке «Страница списка редактирования авторов»:

Рисунок 6.7. Страница списка редактирования авторов

Страница списка редактирования авторов


Мы можем изменить это стандартное поведение, добавив в список дополнительные поля. Было бы удобно, например, если бы на этой странице отображался адрес электронной почты автора и можно было сортировать по имени и фамилии.

Чтобы это реализовать определим класс ModelAdmin для модели Author. Этот класс является ключём к настройке интерфейса администратора и самое простое, что он может — это определить список полей, которые будут отображаться на странице списка редактирования. Приведём admin.py к следующему виду:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email')

admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
admin.site.register(Book)

Вот, что мы сделали:

  1. Мы создали класс AuthorAdmin. Этот класс, унаследованый от django.contrib.admin.ModelAdmin, содержит настройки для конкретной модели в интерфейсе администратора. Мы изменили только одну настройку — list_display, назначив ей кортеж с именами полей, которые будут отображаться на странице списка редактирования. Естественно, модель должна содержать перечисленные поля.

  2. Мы изменили вызов admin.site.register(), добавив AuthorAdmin после Author. Это можно прочитать как: «Зарегестрировать модель Author с настройками AuthorAdmin».

    Функция admin.site.register() принимает унаследованый от ModelAdmin класс, как необязательный аргумент. Если вы не указали второй аргумент(как в случае с Book и Publisher), Django будет использовать настройки по-умолчанию для этой модели.

Внеся новые настройки, обновляем страницу списка редактирования авторов, и вы увидите, что на странице теперь отображается три колонки — имя, фамилия и email-адресс. К тому же, можно производить сортировку по колонкам с помощью нажатия на их заголовок. (См. рисунок «Страница списка редактирования авторов с опцией list_display»):

Рисунок 6.8. Страница списка редактирования авторов с опцией list_display

Страница списка редактирования авторов с опцией list_display


Теперь добавим простую панель поиска. Добавьте search_fields в AuthorAdmin, вот так:

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email')
    search_fields = ('first_name', 'last_name')

Обновите страницу и вы увидите панель поиска вверху. (См. рисунок «Страница списка редактирования авторов с опцией search_fields».) Мы просто указали странице со списком редактирования, чтобы она отобразила панель поиска, которая производит поиск по полям first_name и last_name. Как можно ожидать, поиск регистронезависимый и работает с обеими полями. То есть при поиске строки «bar», будет найдет как автор с именем Barney, так и автор с фамилией Hobarson.

Рисунок 6.9. Страница списка редактирования авторов с опцией search_fields

Страница списка редактирования авторов с опцией search_fields


Теперь добавим фильтр по дате к странице списка редактирования модели Book:

from django.contrib import admin
from mysite.books.models import Publisher, Author, Book

class AuthorAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'email')
    search_fields = ('first_name', 'last_name')

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)

admin.site.register(Publisher)
admin.site.register(Author, AuthorAdmin)
admin.site.register(Book, BookAdmin)

Так как мы работаем с другим набором настроек, мы создали отдельный класс ModelAdmin — BookAdmin. Сначала мы определили list_display для полее приемлимого отображения списка редактирования. Затем установили list_filter, указав кортеж полей для фильтра, который отобразится в правой части страници. Для поля даты, Django предоставляет готовые варианты фильтрации списка: «Сегодня», «Последние 7 дней», «Этот месяц», «Этот год» — разработчики Django нашли их самыми популярными вариантами условий фильтрации. Рисунок «Страница списка редактирования книг с опцией list_filter» показывает, как это выглядит:

Рисунок 6.10. Страница списка редактирования книг с опцией list_filter

Страница списка редактирования книг с опцией list_filter


Параметр list_filter работает с полями разных типов, не только DateField. (Попробуйте, например, с полями BooleanField и ForeignKey.) Фильтры отображаются, если есть хотя бы два значения для фильтрации.

Ещё одним способом фильтрации по дате является использование опции date_hierarchy:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'

К странице списка редактирования сверху добавляется развернутая панель навигации по дате, как показано на рисуноке «Страница списка редактирования книг с опцией date_hierarchy». Она начинается со списка доступных годов, затем месяцев и дней.

Рисунок 6.11. Страница списка редактирования книг с опцией date_hierarchy

Страница списка редактирования книг с опцией date_hierarchy


Обратите внимание, опция date_hierarchy в качестве параметра принимает строку, а не кортеж, потому что только одна дата поля может быть использована для иерархии.

Теперь изменим сортировку по-умолчанию, чтобы на странице списка редактирования, книги сортировались по дате публикации в направлении убывания. По-умолчанию, объекты сортируются в соответствии с атрибутом ordering класса Meta (См. главу «Модели»), но если ordering там не указан, то сортировка не определена.

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)

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

Обновим страницу списка редактирования. Обратите внимание, что возле заголовка поля даты публикации появилась стрелка, указывающая на направление сортировки. (См. рисунок «Страница списка редактирования книг с сортировкой».)

Рисунок 6.12. Страница списка редактирования книг с сортировкой

Страница списка редактирования книг с сортировкой


Мы рассмотрели основные настройки. Используя их, можно создать функциональный и удобный интерфейс администратора всего парой строк кода.

Настройка форм редактирования

Так же, как и со списками редактирования, форма редактирования может быть настроена множеством способов.

Сначала определим порядок отображения полей. По-умолчанию, поля отображаются в том же порядке, в каком они были определены в моделе. Мы можем изменить этот порядок с помощью опции fields в нашем классе, унаследованом от ModelAdmin:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)
    fields = ('title', 'authors', 'publisher', 'publication_date')

Теперь форма редактирования для книг будет использовать указаный порядок полей. Более естественно, если название книги будет идти перед автором. Конечно, порядок полей зависит от вашего способа работы с данными. Все формы разные.

Другой полезной особенностью, которую предоставляет опция fields является исключение определённых полей из списка редактирования. Просто уберите из списка поля, которые требуется исключить. Вы можете использовать это в случае, когда вашим административным пользователям позволено редактировать только определённые части данных или если часть полей изменяется с помощью внешнего автоматизированного процесса. Например, в нашей базе с книгами, мы можем спрятать поле publication_date:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)
    fields = ('title', 'authors', 'publisher')

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

Когда пользователь использует эту неполную форму для добавления книги, Django устанавливает publication_date в None — поэтому убедитесь, что поле имеет свойство null=True.

Другая часто используемая настройка формы редактирования используется для полей типа многие-ко-многим. Как можно было увидеть на форме редактирования для книг, интерфейс администратора представляет каждое поле типа ManyToManyField в виде списка с возможностью выбора нескольких элементов, который является самым логичным методом отображения в формате HTML — но такие списки не всегда удобно использовать. Если вам требуется отметить несколько элементов, вы должны удерживать клавишу Ctrl для этого. Интерфейс администратора добавляет текст, который напоминает об этом, но представьте ситуацию когда надо выделить сотню элементов.

Интенфейс администратора предоставляет решение — filter_horizontal. Добавим его в BookAdmin и посмотрим что получилось:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)
    filter_horizontal = ('authors',)

(Обратите внимание, что мы удалил параметр fields.)

Обновите страницу и вы заметите, что поле «Автор» теперь использует удобный javascript-интерфейс фильтрации, который позволяет искать среди элементов и перемещать выбранных авторов в поле выбранных и наоборот.

Рисунок 6.13. Страница списка редактирования книг с опцией filter_horizontal.

Страница списка редактирования книг с опцией filter_horizontal.


Мы настоятельно рекомендуем использовать filter_horizontal для полей ManyToManyField у которых более 10 элементов. Также вы можете использовать filter_horizontal для нескольких полей, указав их имена в кортеже.

Классы ModelAdmin так же поддерживает опцию filter_vertical. Она работает так же, как и filter_horizontal, но поля располагаются вертикально. Используйте то, что вам больше нравится.

Опции filter_horizontal и filter_vertical работают только с полями ManyToManyField, не с ForeignKey. По-умолчанию, интерфейс администратора использует <select> для полей ForeignKey, но, так же как и для поля ManyToManyField, иногда вы не хотите видеть все объекты в выпадающем списке. Например, если в вашей базе книг будет тысячи авторов, форма добавления книг будет вынуждена загружать всех авторов в выпадающий список.

Методом для решения этой задачи является использование опции raw_id_fields. Укажите для неё кортеж с именами полей ForeignKey и эти поля будут отображаться простым текстовым полем (<input type="text">) вместо <select>. (См. рисунок «Страница списка редактирования книг с опцией raw_id_fields.».)

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'publisher', 'publication_date')
    list_filter = ('publication_date',)
    date_hierarchy = 'publication_date'
    ordering = ('-publication_date',)
    filter_horizontal = ('authors',)
    raw_id_fields = ('publisher',)

Рисунок 6.14. Страница списка редактирования книг с опцией raw_id_fields.

Страница списка редактирования книг с опцией raw_id_fields.


Что вы будете вводить в это поле? Идентификатор издателя. Учитывая то, что люди не могут запомнить идентификаторы из базы данных, рядом находится иконка с увеличительным стеклом, которую вы можете нажат для отображения окна, на котором вы можете выбрать требуемого издателя.


Увидели ошибку?
Выделите её мышкой и нажмите
Ctrl-Enter
Обработано:
1049 49 130 71

Версия книги
1.0 2.0
Версия 2.0 в процессе перевода!

Мой луч
Многообразие света

Полезное
Актуальные вакансии, Python работа для python-разработчиков.


Скачать в формате
CHM от 2 сентября

Заказать PDF файл можно через почту, чат, джаббер. Всего 2WMZ. Содержимое точно соответствует содержимому сайта.
Чем чаще заказываете — тем больше перевожу.

Русская группа

на поддержку перевода
Яндекс Яндекс.Деньги Хочу такую же кнопку
Ускорить процесс перевода!
R130494980980
Z425285133788
E112528079659
U327380922061

Книга помогла реализовать:
Проект «Мой луч»
АРМ УФМС.


Мой вебсайт стоит666 337,31 руб

© 2008-2009 Ruslan Popov @ gmail.com Powered by Django 1.1 beta 1 SVN-11114
Главная | Архив новостей | Общение | Площадка | Примеры OpenID