Курс по Django: https://stepik.org/a/183363
Архив проекта: 39_sitewomen.zip
Продолжаем
настраивать и изучать работу с админ-панелью. Это занятие начнем с добавления
собственного (пользовательского) поля в список статей модели Women. То есть, мы
сформируем (отобразим) новое поле, которого нет в БД. Для этого перейдем в файл
women/admin.py и в классе WomenAdmin пропишем метод
с произвольным названием. Пусть он называется brief_info (краткая
информация). Сам метод будет следующим:
class WomenAdmin(admin.ModelAdmin):
...
def brief_info(self, women: Women):
return f"Описание {len(women.content)} символов."
Он принимает
дополнительный параметр, который я назвал women, и ссылается на
объект класса модели Women. То есть, при отображении нового
столбца для каждой записи, в этот метод Django автоматически
будет передавать объект класса Women. Для удобства я его аннотировал. А
содержимое столбца – это возвращаемые методом данные в виде строки. То есть, в
нашем примере – это строка с числом символов в статье.
После объявления
метода, мы можем его указывать в списке list_display. Для удобства я уберу из
него поле ‘id’ и добавлю поле
по имени метода brief_info следующим
образом (также поле id следует убрать из списка list_display_links):
class WomenAdmin(admin.ModelAdmin):
list_display = ('title', 'time_create', 'is_published', 'cat', 'brief_info')
list_display_links = ('title', )
list_editable = ('is_published', )
ordering = ['-time_create', 'title']
list_per_page = 5
def brief_info(self, women: Women):
return f"Описание {len(women.content)} символов."
Перейдем теперь
в админ-панель, обновим ее, и увидим новый столбец в списке наших постов.
Давайте изменим его название. Для этого достаточно перед методом прописать
специальный декоратор admin.display следующим образом:
@admin.display(description="Краткое описание")
def brief_info(self, women: Women):
return f"Описание {len(women.content)} символов."
Параметр description
этого декоратора, как раз и определяет название столбца в админ-панели. Обновим
ее и увидим указанный заголовок:
Однако сейчас
новая колонка не поддерживает сортировку. Дело в том, что Django просто не знает
по какому критерию ее сортировать. При необходимости это тоже можно указать в
декораторе admin.display с помощью дополнительного параметра ordering:
@admin.display(description="Краткое описание", ordering='content')
def brief_info(self, women: Women):
return f"Описание {len(women.content)} символов."
В результате
сортировка будет происходить в соответствии с порядком сортировки поля content. Но это не то,
что нам нужно, поэтому я уберу этот параметр, а также пагинацию.
Обратите
внимание, что мы не можем пользовательские поля указывать как сортируемые в
коллекции ordering. Получим
ошибку. Их сортировка может выполняться только на базе других существующих в
таблице полей.
По аналогии
можно добавлять любые другие колонки с требуемой информацией.
Создание пользовательских действий
Во второй части
занятия мы с вами научимся добавлять свои действия в админ-панель. На самом
верху списка расположен combobox с одним действием «Удалить
выбранные записи». Давайте сюда добавим еще одно действие, которое будет
устанавливать статус «Опубликовано» всем выбранным статьям. Для этого в класс WomenAdmin
добавим еще один метод, допустим, с именем set_published:
def set_published(self, request, queryset):
queryset.update(is_published=Women.Status.PUBLISHED)
Он принимает два
дополнительных обязательных параметра: request – объект
запроса; queryset – объект QuerySet с выбранными
записями. Затем, используя набор записей, мы для них вызываем метод update() и изменяем
поле is_published на значение PUBLISHED.
Чтобы этот метод
был использован в качестве действия в админ-панели, его нужно указать в списке actions класса WomenAdmin:
actions = ['set_published']
После обновления
страницы увидим название этого метода в списке действий. Давайте выберем
несколько записей и выполним для них эту команду. Видим, что для указанных
записей был изменен статус на «Опубликовано». Осталось поменять название
действия в списке. Для этого следует воспользоваться специальным декоратором:
@admin.action(description="Опубликовать выбранные записи")
def set_published(self, request, queryset):
queryset.update(is_published=Women.Status.PUBLISHED)
Обновляем
страницу и видим это название в действиях админ-панели.
Давайте еще
немного улучшим работу нашего действия, а именно, пусть дополнительно выводится
сообщение о том, сколько записей было изменено. Для этого воспользуемся
специальным методом message_user(), доступный
для админ-панели, следующим образом:
@admin.action(description="Опубликовать выбранные записи")
def set_published(self, request, queryset):
count = queryset.update(is_published=Women.Status.PUBLISHED)
self.message_user(request, f"Изменено {count} записи(ей).")
Отметим
несколько записей для изменения и видим появление нашего сообщения.
Раз у нас есть
действия для публикации выбранных записей, то логично было бы сделать обратное
действие – снятие выбранных записей с публикации. Делается это аналогичным
образом:
@admin.action(description="Снять с публикации выбранные записи")
def set_draft(self, request, queryset):
count = queryset.update(is_published=Women.Status.DRAFT)
self.message_user(request, f"{count} записи(ей) сняты с публикации!", messages.WARNING)
Смотрите, мы
здесь в методе message_user() дополнительно
указали флаг messages.WARNING для отображения
сообщения как предупреждения, что публикации были сняты. После выбора записей и
выполнения команды снятия с публикации, увидим ожидаемый результат.
Вот так
достаточно просто добавлять свои собственные поля в список отображения записей
и создавать свои собственные действия.
Курс по Django: https://stepik.org/a/183363