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 = 'Опубліковано нещодавно?'  # Налаштування заголовка стовпця

# 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)

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

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ