📖 Теория: Инлайн-формы в 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
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 к модели:
- Создать модели с ForeignKey-связью и выполнить миграции
- Определить Inline-класс, унаследованный от
TabularInlineилиStackedInline - Создать (или обновить) класс ModelAdmin с атрибутом
inlines - Зарегистрировать обе модели в 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— ссылка на объект ModelAdminrequest— объект 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 вручную.