Django 5 для начинающих

Прогресс по курсу:  9/1004

5.3 Сайт администрирования
2 из 2 шагов пройдено

Адаптация внешнего вида моделей под конкретно-прикладную задачу

Теперь давайте посмотрим на способы адаптации сайта администрирования под конкретно-прикладную задачу.

Отредактируйте файл admin.py приложения blog, изменив его, как показано ниже:

from django.contrib import admin
from .models import Post


@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ['title', 'slug', 'author', 'publish', 'status']

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

Атрибут list_display позволяет задавать поля модели, которые вы хотите показывать на странице списка объектов администрирования.

Декоратор @admin.register() выполняет ту же функцию, что и функция admin.site.register(), которую вы заменили, регистрируя декорируемый им класс ModelAdmin.

Давайте адаптируем модель admin, внеся в нее еще несколько опций.

Отредактируйте файл admin.py приложения blog, изменив его, как показано ниже:

from django.contrib import admin
from .models import Post


@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
    list_display = ['title', 'slug', 'author', 'publish', 'status']
    list_filter = ['status', 'created', 'publish', 'author']
    search_fields = ['title', 'body']
    prepopulated_fields = {'slug': ('title',)}
    raw_id_fields = ['author']
    autocomplete_fields = ['author']
    date_hierarchy = 'publish'
    ordering = ['status', 'publish']

Вернитесь в свой браузер и перезагрузите страницу списка постов. Теперь она будет выглядеть примерно так:

Вы видите, что отображаемые на странице списка постов поля соответствуют тем, которые мы указали в атрибуте list_display.

Теперь страница списка содержит правую боковую панель, которая позволяет фильтровать результаты по полям, включенным в атрибут list_filter.

На странице появилась строка поиска. Это вызвано тем, что мы определили список полей, по которым можно выполнять поиск, используя атрибут search_fields.

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

Вы также видите, что по умолчанию посты упорядочены по столбцам STATUS(Статус) и PUBLISH(Опубликован). С помощью атрибута ordering были заданы критерии сортировки, которые будут использоваться по умолчанию.

Далее кликните по ссылке ADD POST(Добавить пост). Здесь вы тоже заметите некоторые изменения. При вводе заголовка нового поста поле slug заполняется автоматически.

Вы сообщили Django, что нужно предзаполнять поле slug данными, вводимыми в поле title, используя атрибут prepopulated_fields:

Кроме того, теперь поле author отображается поисковым виджетом, который будет более приемлемым, чем выбор из выпадающего списка, когда у вас тысячи пользователей.

Это достигается с помощью атрибута raw_id_fields и выглядит следующим образом:

Всего несколькими строками исходного кода мы адаптировали отображение модели на сайте администрирования.

Более подробная информация о сайте администрирования находится на странице https://docs.djangoproject.com/en/5.0/ref/contrib/admin/


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

 

Как вариант)

Здесь может возникнуть естественное желание искать по автору или идентификатору поста в базе данных (особенно, если речь не посте, а о сущности, которую лучше идентифицировать по ункальному номеру) - но делается это неочевидно.

В таком случае список поисковых полей будет таким: list_filter = ['id', 'author__username', 'status', 'created', 'publish', 'author']

Двойное подчёркивание в данном случае позволяет перемещаться вверх по модели данных, а id это автосоздаваемый ключ. Просто указать author не выйдет - при таком указании выводится отображаемое имя, поиск по нему невозможен. 

https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields

Однако, если также добавить в list_filter , например, email для поиска пользователя, то уже в list_display нельзя использовать перемещение по модели. То есть поиск постов по email будет работать, но вывести в таблице это поле не получится (кроме как добавить в отображаемое имя объекта), что кажется противоречивым. Простого способа реализовать отображение полей связанных моделей я не нашёл, если у кого есть идеи - пожалуйста, напишите.

Изменен Oleg Romanov

@Oleg_Romanov, если я правильно понял вопрос, то у меня получилось следующее решение (осторожно, костыли*):

https://pastebin.com/jN9HD6cX

В этом примере мы создали два собственных фильтра: AuthorUsernameFilter и AuthorEmailFilter. Они позволяют фильтровать записи по имени пользователя и почтовому адресу автора, используя выпадающие списки в админ-панели. Затем мы добавили эти фильтры в list_filter и определили методы author_username и author_email, чтобы отображать соответствующие значения в списке записей list_display.

*Нужно понимать, что такие неоптимизированные запросы, как: ... for author in User.objects.all() будут ложить вам базу на проде. Поэтому данное решение подходит только в учебных целях.

Изменен Anonymous 450292901

Предлагаю к полю raw_id_fields = ['author'] ниже добавить autocomplete_fields = ['author'], упрощает выбор автора в разы.

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

Изменен Александр Павлов

@Александр_Павлов, Спасибо, добавил. В ближайшее время переделаем скриншоты.

Спасибо за обзор интересных опций. Особенно prepopulated_fields.  

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

Изменен Кирилл Семенихин

@Кирилл_Семенихин, персонала как бы смешно это не звучало ааххахах лол 

В данном атрибуте list_filter = ['status', 'created', 'publish', 'author'] есть автор. А почему на самом сайте его нет? 

@Yernur_Satybaldiyev, поле автор было добавлено в модель в шаге 5.2.3.

    author = models.ForeignKey(User,
                               on_delete=models.CASCADE,
                               related_name='blog_posts')