JavaRush /Курсы /Модуль 3: Django /Создание и использование ModelAdmin

Создание и использование ModelAdmin

Модуль 3: Django
11 уровень , 3 лекция
Открыта

Если сравнить работу с моделью в админке с управлением автомобилем, то регистрация модели через admin.site.register() — это как ехать на автомобиле без руля. Вы можете только ехать прямо, но не можете повернуть. А вот ModelAdmin — это ваш руль. Он предоставляет полный набор настроек для:

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

Давайте разберемся, как настроить ModelAdmin для наших моделей и начать рулить интерфейсом админа!

Основы создания ModelAdmin

ModelAdmin — это класс, который связывается с моделью и позволяет переопределять её поведение в админ-зоне. Начнем с создания простой модели и привязки её к кастомизированному ModelAdmin.

Создадим модель для управления книгами в библиотеке:

# models.py
from django.db import models

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    published_date = models.DateField()
    isbn_number = models.CharField(max_length=13, unique=True)
    genre = models.CharField(max_length=50)

    def __str__(self):
        return self.title

Контролировать работу модели через админ-зону мы будем с помощью класса ModelAdmin. Для этого создадим отдельный класс и зарегистрируем его:

# admin.py
from django.contrib import admin
from .models import Book

class BookAdmin(admin.ModelAdmin):
    pass  # Пока ничего не настраиваем

admin.site.register(Book, BookAdmin)

После регистрации модель будет доступна в админке, но что если нам нужно изменить отображение полей или поведение?

Использование атрибутов ModelAdmin

  1. list_display: для отображения полей в списке объектов

По умолчанию в списке объектов Django Admin отображает только строковое представление модели (то, что возвращает метод __str__). Вы можете точно указать, какие поля хотите видеть.

# admin.py
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date', 'isbn_number')

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

# models.py
class Book(models.Model):
    # ... всё как раньше
    def is_recent(self):
        return self.published_date.year > 2000
    is_recent.short_description = 'Published Recently?'  # Настройка заголовка столбца

# admin.py
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date', 'is_recent')
  1. list_filter: добавление фильтров

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

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date')
    list_filter = ('author', 'genre', 'published_date')

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

  1. search_fields: настройка поиска

Поиск позволяет выполнять фильтрацию по заданным полям. Будем искать книги по названию и автору:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date')
    list_filter = ('genre',)
    search_fields = ('title', 'author')

Теперь в верхней части админки появится строка поиска. Вводите название или имя автора, и Django найдет совпадения.

  1. Сортировка объектов: ordering

Допустим, вы хотите, чтобы книги в списке отображались по дате издания в обратном порядке. Это легко настроить:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date')
    ordering = ('-published_date',)  # Сортировка по убыванию даты
  1. readonly_fields: защита полей от редактирования

Если нужно запретить изменение определённых полей, используйте readonly_fields:

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'isbn_number')
    readonly_fields = ('isbn_number',)  # Поле ISBN будет только для чтения

Теперь в форме редактирования поле ISBN будет заблокировано для изменения.

  1. Настройка формы редактирования: fields и fieldsets

Форма редактирования объекта может быть упорядочена согласно вашему предпочтению. Это делается с помощью атрибута fields или fieldsets.

class BookAdmin(admin.ModelAdmin):
    fields = ('title', 'author', 'published_date', 'genre', 'isbn_number')

Если же хочется сгруппировать поля в логические блоки, используйте fieldsets:

class BookAdmin(admin.ModelAdmin):
    fieldsets = (
        ('Основная информация', {
            'fields': ('title', 'author', 'genre')
        }),
        ('Дополнительная информация', {
            'fields': ('published_date', 'isbn_number'),
            'classes': ('collapse',),  # Раздел можно свернуть
        }),
    )

Методы ModelAdmin для более глубоких кастомизаций

Иногда статичных атрибутов недостаточно, и мы хотим кастомизировать поведение админ-зоны. ModelAdmin предоставляет методы, которые можно переопределить.

  1. get_queryset: изменение списка объектов

Вы можете настроить, какие объекты отображать в списке:

class BookAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # Показываем только книги, изданные в 21 веке
        return qs.filter(published_date__year__gte=2000)
  1. save_model: действия при сохранении объекта

Этот метод позволяет выполнить действия при сохранении объекта в админке:

class BookAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        if not change:  # Если это новый объект
            obj.title = obj.title.upper()  # Автоматически переводим название в верхний регистр
        super().save_model(request, obj, form, change)

Полный пример BookAdmin

Теперь объединим всё, что мы узнали, в одном классе:

# admin.py
class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'published_date', 'is_recent')
    list_filter = ('genre', 'published_date')
    search_fields = ('title', 'author')
    ordering = ('-published_date',)
    readonly_fields = ('isbn_number',)
    fieldsets = (
        ('Основная информация', {
            'fields': ('title', 'author', 'genre')
        }),
        ('Дополнительная информация', {
            'fields': ('published_date', 'isbn_number'),
            'classes': ('collapse',),  # Раздел можно свернуть
        }),
    )

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # Показываем только книги с жанром "фантастика"
        return qs.filter(genre='фантастика')

    def save_model(self, request, obj, form, change):
        if not change:  # Если это новая книга
            obj.title = obj.title.upper()
        super().save_model(request, obj, form, change)

admin.site.register(Book, BookAdmin)

Теперь наша админка не только функциональная, но и хорошо кастомизирована под задачи управления книгами!

1
Задача
Модуль 3: Django, 11 уровень, 3 лекция
Недоступна
Настройка отображения модели в админ-зоне
Настройка отображения модели в админ-зоне
1
Задача
Модуль 3: Django, 11 уровень, 3 лекция
Недоступна
Дополнительная кастомизация формы редактирования
Дополнительная кастомизация формы редактирования
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ