💻 Примеры: Инлайн-формы и Admin Actions
⚡ Ключевые примеры
# models.py
class Publisher(models.Model):
name = models.CharField(max_length=100)
established_date = models.DateField()
def __str__(self): return self.name
class Book(models.Model):
title = models.CharField(max_length=200)
publisher = models.ForeignKey(
Publisher, on_delete=models.CASCADE, null=True, blank=True
)
# admin.py — TabularInline
class BookInline(admin.TabularInline):
model = Book
extra = 1
@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline]
Пример 1: Модели Publisher и Book
Из лекции: создаём модель Publisher и добавляем ForeignKey в Book.
# models.py
from django.db import models
class Publisher(models.Model): # NEW MODEL
name = models.CharField(max_length=100)
established_date = models.DateField()
def __str__(self):
return self.name
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
def __str__(self):
return f"{self.first_name} {self.last_name}"
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
published_date = models.DateField()
publisher = models.ForeignKey(
Publisher,
on_delete=models.CASCADE,
null=True,
blank=True
) # NEW FIELD
def __str__(self):
return f"{self.title} by {self.author}"
class Meta:
ordering = ['title']
После изменения моделей — обязательно выполнить миграции:
python manage.py makemigrations
python manage.py migrate
Пример 2: TabularInline (из лекции)
Минимальная настройка — книги отображаются в табличном формате на странице издательства.
# admin.py
from django.contrib import admin
from .models import Book, Publisher
class BookInline(admin.TabularInline):
model = Book
extra = 1 # 1 пустая строка для новой книги
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline]
admin.site.register(Publisher, PublisherAdmin)
admin.site.register(Book)
Результат: при открытии страницы редактирования Publisher в Admin, внизу страницы появится секция «Books» с табличной формой для добавления/редактирования книг.
Пример 3: StackedInline (из лекции)
Тот же результат, но каждая книга отображается отдельным блоком:
class BookInline(admin.StackedInline):
model = Book
extra = 1
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline]
admin.site.register(Publisher, PublisherAdmin)
admin.site.register(Book)
Пример 4: Расширенная настройка Inline
Современный стиль с @admin.register и дополнительными атрибутами:
from django.contrib import admin
from .models import Book, Publisher
class BookInline(admin.TabularInline):
model = Book
extra = 1
max_num = 20
fields = ['title', 'published_date']
readonly_fields = []
can_delete = True
show_change_link = True # ссылка на отдельную страницу книги
@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline]
list_display = ['name', 'established_date']
search_fields = ['name']
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'publisher', 'published_date']
search_fields = ['title', 'author__first_name']
list_filter = ['publisher']
Пример 5: Admin Action — обновление поля (из лекции)
Сначала добавим поле created_at к модели Book:
# models.py — добавляем поле
class Book(models.Model):
...
created_at = models.DateTimeField(null=True, blank=True) # NEW FIELD
python manage.py makemigrations
python manage.py migrate
Теперь создаём action для массового обновления поля created_at:
# admin.py
from django.contrib import admin
from django.utils import timezone
from .models import Book, Publisher
class BookInline(admin.TabularInline):
model = Book
extra = 1
@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline]
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ['title', 'author', 'created_at']
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]
Как использовать Action:
- Открыть список Book в Admin
- Отметить нужные книги чекбоксами
- В выпадающем списке «Action» выбрать «Update created_at to current time»
- Нажать «Go»
Пример 6: Action с декоратором @admin.action (Django 3.2+)
Современный способ задать short_description через декоратор:
from django.contrib import admin
from django.utils import timezone
@admin.action(description="Установить created_at = сейчас")
def update_created_at(modeladmin, request, queryset):
queryset.update(created_at=timezone.now())
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
actions = [update_created_at]
⚠️ Проверить по документации: декоратор
@admin.action доступен с Django 3.2. В Django 5.x — рекомендуемый способ.
Пример 7: Несколько Inline на одной странице
Можно добавить сразу несколько Inline-классов к одному ModelAdmin:
class ReviewInline(admin.TabularInline):
model = Review
extra = 0 # не показывать пустые строки
max_num = 5
class BookInline(admin.TabularInline):
model = Book
extra = 1
@admin.register(Publisher)
class PublisherAdmin(admin.ModelAdmin):
inlines = [BookInline, ReviewInline] # оба Inline