Теперь мы уверенно управляем базовыми моделями через мощный интерфейс Django Admin. Однако реальная разработка часто сопровождается моделями, связанными через ForeignKey, ManyToMany или OneToOne. Удобно ли переключаться между страницами для управления этими данными? Конечно, нет! Именно здесь на сцену выходит InlineModelAdmin.
InlineModelAdmin – это специальный вид кастомизации в Django Admin, который позволяет встроить управление связанными объектами прямо в интерфейс родительской модели. Когда у нас есть связанные модели (например, одна статья — и множество комментариев), InlineModelAdmin помогает редактировать как родительскую, так и связанные дочерние модели на одной странице. Это значительно экономит время и делает процесс управления данными более удобным.
Django предоставляет два подкласса для работы с InlineModelAdmin:
TabularInline: отображает записи в виде таблицы.StackedInline: отображает записи в виде вертикально расположенных блоков.
Пример применения InlineModelAdmin
Представим простую ситуацию: у нас есть блоговые статьи и комментарии к этим статьям. Мы хотим, чтобы администратор мог редактировать и добавлять комментарии прямо с интерфейса редактирования статьи. Вот как мы можем этого добиться.
Шаг 1: создаём модели
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Comment(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comments')
author = models.CharField(max_length=100)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Comment by {self.author}"
Вот что у нас есть:
- Модель
Articleпредставляет статьи блога. - Модель
Comment— комментарии, связанные с конкретными статьями через полеForeignKey.
Шаг 2: регистрация моделей в админ-зоне
Для начала зарегистрируем обе модели в админ-зоне, чтобы понять, как это будет выглядеть без InlineModelAdmin.
from django.contrib import admin
from .models import Article, Comment
admin.site.register(Article)
admin.site.register(Comment)
На странице Django Admin будет две отдельные секции — одна для управления статьями, другая для управления комментариями. Уже более-менее, но всё ещё неэффективно. Попробуем объединить их.
Использование TabularInline и StackedInline
Шаг 3: Создаём Inline для комментариев
Давайте зарегистрируем Comment как встроенную модель для Article, чтобы можно было управлять комментариями прямо со страницы редактирования статьи.
Пример с использованием TabularInline:
from django.contrib import admin
from .models import Article, Comment
class CommentInline(admin.TabularInline):
model = Comment
extra = 1 # Количество пустых форм для добавления новых объектов
fields = ('author', 'text', 'created_at') # Поля, отображаемые в таблице
readonly_fields = ('created_at',) # Поля только для чтения
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'published_date')
inlines = [CommentInline]
Что здесь происходит?
- Мы создали класс
CommentInline, который наследуется отadmin.TabularInline. - Указали модель
Comment, которую нужно встроить. - С помощью параметра
extraзадали количество пустых строк для добавления новых комментариев. Теперь администратор сможет сразу добавлять комментарии прямо в админке. - Параметр
fieldsконтролирует, какие поля будут видны для редактирования. - Поле
created_atстало доступно только для чтения благодаряreadonly_fields.
Теперь страница редактирования статьи выглядит привлекательно: комментарии отображаются в удобной табличной форме, и мы можем не только редактировать существующие комментарии, но и создавать новые.
Шаг 4: использование StackedInline
Иногда для связанных объектов требуется более богатое представление. Например, если дочерние модели имеют много полей. В таком случае вместо табличного вида можно использовать вертикальный (StackedInline).
class CommentInline(admin.StackedInline):
model = Comment
extra = 1
fields = ('author', 'text', 'created_at')
readonly_fields = ('created_at',)
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title', 'published_date')
inlines = [CommentInline]
Теперь комментарии отображаются в виде вертикальных карточек под формой редактирования статьи. Выбор между TabularInline и StackedInline зависит от ваших данных и предпочтений.
Работа с другими типами связей
Мы уже рассмотрели пример с ForeignKey. Подобная настройка работает идеально, когда дочерняя модель ссылается на родительскую.
С ManyToMany связями Inline работает также хорошо. Рассмотрим пример.
Шаг 1: Изменим модели
Добавим к нашим статьям теги.
class Tag(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
tags = models.ManyToManyField(Tag, related_name='articles')
def __str__(self):
return self.title
Шаг 2: Создаём Inline для ManyToMany
Для работы с ManyToMany связями нам нужно использовать промежуточную модель или прямую связь. Django Admin инлайн автоматически работает только с конкретными объектами.
class TagInline(admin.TabularInline):
model = Article.tags.through # Работаем через промежуточную модель
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('title',)
inlines = [TagInline]
@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
list_display = ('name',)
Теперь можно управлять связями между статьями и тегами прямо со страницы редактирования статьи.
Утончённая кастомизация InlineModelAdmin
Если вы хотите добавить дополнительную логику, например, фильтровать связанные объекты или ограничивать их отображение, вы можете переопределить методы get_queryset и другие.
class CommentInline(admin.TabularInline):
model = Comment
def get_queryset(self, request):
# Отображаем только комментарии определённых авторов
qs = super().get_queryset(request)
return qs.filter(author='John Doe')
Практическое применение
Django Admin с InlineModelAdmin часто используется для:
- Управления заказами и вложенными строками товаров в e-commerce.
- Редактирования событий и участников для расписаний.
- Управления проектами и задачами с вложенными моделями.
Для любого проекта, где у вас есть связанные данные, InlineModelAdmin сокращает время на переходы между моделями и делает интерфейс администрирования более удобным.
Не забудьте экспериментировать! Даже если вам кажется, что всё работает, попробуйте TabularInline вместо StackedInline и посмотрите, какой интерфейс удобнее для вас и вашей команды.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ