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 inline автоматично працює тільки з конкретними об'єктами.

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

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ