← К оглавлению урока

📖 Теория: Инлайн-формы в Admin-панели

⚡ Кратко

  • TabularInline — компактный таблицей, хорошо для простых моделей с малым числом полей
  • StackedInline — каждый объект отдельным блоком, хорошо если полей много
  • extra = N — сколько пустых строк показывать для новых объектов
  • max_num = N — ограничить максимальное число связанных объектов
  • Inline подключается через inlines = [MyInline] в ModelAdmin
  • Admin Action: метод с сигнатурой def my_action(self, request, queryset)

Что такое инлайн-формы

Инлайн-формы (Inline) в Django Admin позволяют редактировать связанные модели на одной странице с основной моделью. Это особенно полезно для отношений один-ко-многим (ForeignKey), когда нужно, например, добавить несколько книг издательства прямо на странице редактирования издательства.

Зачем нужны Inline? Без Inline для добавления книг к Publisher нужно сначала сохранить Publisher, потом перейти в раздел Books, выбрать нужного Publisher… С Inline это делается на одной странице в один шаг.

Два вида Inline

TabularInline

Отображает связанные объекты в табличном формате: каждый объект — строка таблицы, поля — столбцы. Подходит для случаев, когда:

  • У связанных объектов мало полей
  • Нужно компактно разместить много связанных объектов
  • Важна наглядность при одновременном просмотре нескольких записей
from django.contrib import admin
from .models import Book, Publisher

class BookInline(admin.TabularInline):
    model = Book
    extra = 1

class PublisherAdmin(admin.ModelAdmin):
    inlines = [BookInline]

admin.site.register(Publisher, PublisherAdmin)
admin.site.register(Book)

StackedInline

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

  • У связанных объектов много полей
  • Важна читаемость при редактировании
  • Не нужно видеть много объектов одновременно
class BookInline(admin.StackedInline):
    model = Book
    extra = 1

class PublisherAdmin(admin.ModelAdmin):
    inlines = [BookInline]

Настройки Inline-классов

extra

Определяет количество пустых форм для ввода новых объектов, которые отображаются по умолчанию.

class BookInline(admin.TabularInline):
    model = Book
    extra = 3  # показать 3 пустые строки для новых книг

max_num

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

class BookInline(admin.TabularInline):
    model = Book
    extra = 1
    max_num = 10  # не более 10 книг у одного издательства

fields

Ограничивает набор полей, отображаемых в Inline.

class BookInline(admin.TabularInline):
    model = Book
    fields = ['title', 'published_date']  # только эти поля

readonly_fields

Поля, которые отображаются, но недоступны для редактирования.

class BookInline(admin.TabularInline):
    model = Book
    readonly_fields = ['created_at']

can_delete

Управляет отображением чекбокса «Удалить» рядом с каждым объектом. По умолчанию True.

class BookInline(admin.TabularInline):
    model = Book
    can_delete = False  # запретить удаление через Inline

Полная настройка Admin с Inline

Шаги для подключения Inline к модели:

  1. Создать модели с ForeignKey-связью и выполнить миграции
  2. Определить Inline-класс, унаследованный от TabularInline или StackedInline
  3. Создать (или обновить) класс ModelAdmin с атрибутом inlines
  4. Зарегистрировать обе модели в Admin
from django.contrib import admin
from .models import Book, Publisher

# Шаг 2: Inline-класс
class BookInline(admin.TabularInline):
    model = Book
    extra = 1
    fields = ['title', 'published_date']

# Шаг 3: ModelAdmin с Inline
class PublisherAdmin(admin.ModelAdmin):
    inlines = [BookInline]
    list_display = ['name', 'established_date']

# Шаг 4: Регистрация
admin.site.register(Publisher, PublisherAdmin)
admin.site.register(Book)

Пользовательские действия (Admin Actions)

В Django Admin можно добавлять кастомные действия (actions) — операции, которые применяются к нескольким выбранным объектам одновременно. По умолчанию в Admin есть только одно действие: «Удалить выбранное».

Типичные сценарии: массовая публикация/снятие с публикации, обновление статуса, экспорт, отправка уведомлений.

Сигнатура функции-действия

def my_action(self, request, queryset):
    # queryset — QuerySet из выбранных объектов
    queryset.update(field=value)
  • self — ссылка на объект ModelAdmin
  • request — объект HttpRequest текущего запроса
  • queryset — набор выбранных администратором объектов

Полный пример: Action для обновления поля

from django.utils import timezone

class BookAdmin(admin.ModelAdmin):
    def update_created_at(self, request, queryset):
        queryset.update(created_at=timezone.now())

    update_created_at.short_description = "Update created_at to current time"

    actions = [update_created_at]

short_description

Атрибут функции — текст, который отображается в выпадающем списке действий в Admin. Без него Django будет использовать имя функции.

Массовые ORM-операции в actions

Для эффективного обновления большого количества объектов используются bulk-методы:

# Массовое обновление (один SQL UPDATE)
queryset.update(status='done')

# Массовое создание (один SQL INSERT)
Model.objects.bulk_create([obj1, obj2, obj3])

# Массовое обновление конкретных полей
Model.objects.bulk_update(objects_list, ['field1', 'field2'])
⚠️ Проверить по документации: queryset.update() не вызывает метод save() и не триггерит сигналы Django (post_save). Если нужны сигналы — итерировать queryset вручную.