Что такое Django Admin Inline?

Ответ

Django Admin Inline — это функциональность в административной панели Django, которая позволяет редактировать связанные модели непосредственно на странице редактирования родительской модели. Это значительно упрощает управление данными и повышает удобство работы с объектами, связанными отношениями OneToOne, ForeignKey и ManyToMany.

Основные классы для Inline:

  • admin.TabularInline: Отображает связанные объекты в табличном виде, что идеально подходит для компактного представления множества однотипных записей.
  • admin.StackedInline: Отображает каждый связанный объект в виде "стека" полей, аналогично стандартной форме редактирования модели, что удобно для объектов с большим количеством полей.

Пример использования:

Предположим, у нас есть модели Author и Book, где Book имеет ForeignKey на Author.

# models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    publication_date = models.DateField()

    def __str__(self):
        return self.title
# admin.py
from django.contrib import admin
from .models import Author, Book

# Определяем Inline для модели Book
class BookInline(admin.TabularInline):
    model = Book  # Указываем связанную модель
    extra = 1     # Количество пустых форм для добавления новых связанных объектов
    fields = ['title', 'publication_date'] # Какие поля показывать в inline

# Регистрируем модель Author в админке и добавляем BookInline
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    inlines = [BookInline] # Добавляем BookInline к админке автора
    list_display = ['name']

Ключевые параметры Inline классов:

  • model: Обязательный параметр, указывающий связанную модель.
  • extra: Количество дополнительных пустых форм, отображаемых для добавления новых связанных объектов.
  • max_num: Максимальное количество связанных объектов, которые можно редактировать или добавлять.
  • fields: Кортеж или список полей, которые будут отображаться в inline-форме.
  • readonly_fields: Кортеж или список полей, которые будут отображаться только для чтения.
  • fk_name: Используется для явного указания имени внешнего ключа, если у родительской модели несколько внешних ключей на дочернюю, или для OneToOneField, который не является первичным ключом.

Ответ 18+ 🔞

А, ну это ж про админку Джанги, где можно всё в кучу запихнуть! Слушай, представь: у тебя есть автор, а у него книги. И вместо того чтобы бегать по разным страницам, ты можешь прямо на странице автора его книги добавлять, править, удалять — всё в одном месте, как в хорошем шкафу, где носки лежат рядом с ботинками. Удобно, блядь!

Вот смотри, как это выглядит под капотом. Есть два основных способа это оформить:

  1. admin.TabularInline — это когда всё аккуратненько в табличку, строчка за строчкой. Идеально, если полей немного и ты хочешь видеть сразу много записей. Экономия места — овердохуища!
  2. admin.StackedInline — а это когда каждая связанная запись разворачивается как отдельная, полноценная форма, поля друг под другом. Для сложных объектов, где полей дохуя и в таблицу их не впихнёшь.

Пример из жизни, чтобы не ебать мозг:

Допустим, есть модель Author (Автор) и Book (Книга). Книга привязана к автору через ForeignKey. Без inline'ов пришлось бы сначала автора создать, потом отдельно искать форму для добавления книг и там его выбирать. Задолбаешься, блядь!

А с inline'ами делаем так:

# models.py — тут всё как обычно, ничего нового
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    # ... может, ещё борода и степень алкоголизма

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE) # Вот эта связка, сука, главная!
    publication_date = models.DateField(null=True, blank=True)

    def __str__(self):
        return self.title

А теперь магия в admin.py:

# admin.py
from django.contrib import admin
from .models import Author, Book

# Создаём inline для книг. Пусть будет в табличном виде — компактнее.
class BookInline(admin.TabularInline):  # Или admin.StackedInline, если хочешь простор
    model = Book  # Обязательно говорим, какую модель прицепляем
    extra = 1     # Это сколько пустых форм для новых книг показывать по умолчанию. Поставил 3 — получишь три пустые строки сразу. Хуй с ним, пусть будет одна.
    # Можно указать, какие конкретно поля показывать, а то вдруг там секретное поле 'royalties' (гонорары), которое автору лишний раз видеть не надо
    fields = ('title', 'publication_date')
    # А можно некоторые поля сделать readonly, чтобы только смотреть, но не трогать
    # readonly_fields = ('isbn',)

# Теперь цепляем этот inline к админке автора
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    # Самое главное — говорим: "Джанга, вот тебе inline, вставь его в форму автора"
    inlines = [BookInline]
    list_display = ['name', 'book_count']  # Это уже для списка авторов, не обязательно

    # Доп. фишка: можно метод добавить, чтобы в списке авторов видно было, сколько у него книг
    def book_count(self, obj):
        return obj.book_set.count()
    book_count.short_description = 'Количество книг'

И что в итоге? Заходишь ты в админку, открываешь какого-нибудь автора, а там снизу, прямо на той же странице, аккуратная табличка со всеми его книгами. Можешь новые добавить, старые поправить или нахуй удалить. Красота, ёпта!

Ещё несколько полезных параметров, чтобы не облажаться:

  • model: Без этого нихуя не работает. Указываешь, какую модель inline'ишь.
  • extra: Сколько пустых форм для добавления нового показать. Поставишь 0 — придётся жать на "добавить ещё", ленивая жопа.
  • max_num: Максимальное количество связанных объектов, которые можно воткнуть. Чтобы какой-нибудь плодовитый автор не заспамил тебе базу 5000 книг про одного и того же ебаного кота.
  • fk_name: Важный, блядь! Если у родительской модели (например, Author) несколько связей ForeignKey на одну и ту же дочернюю модель (например, две ссылки на Book: published_books и unpublished_books), то нужно явно указать, какую именно связь использовать. Или для OneToOneField, который не является первичным ключом. А то Джанга запутается и начнёт хуйню какую-то делать.

В общем, инструмент — огонь. Сначала кажется, что какая-то магия, а потом привыкаешь и без него как без рук. Главное — правильно связать модели и не перепутать fk_name, а то будет "вротберунчик" и ничего не заработает.