JavaRush /Курсы /Модуль 3: Django /Использование InlineModelAdmin для связанных объектов

Использование InlineModelAdmin для связанных объектов

Модуль 3: Django
11 уровень , 5 лекция
Открыта

Теперь мы уверенно управляем базовыми моделями через мощный интерфейс 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 и посмотрите, какой интерфейс удобнее для вас и вашей команды.

1
Задача
Модуль 3: Django, 11 уровень, 5 лекция
Недоступна
Добавление InlineModelAdmin для связанных объектов
Добавление InlineModelAdmin для связанных объектов
1
Задача
Модуль 3: Django, 11 уровень, 5 лекция
Недоступна
Настройка ManyToMany связи с InlineModelAdmin
Настройка ManyToMany связи с InlineModelAdmin
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ