Django で関連モデルをインライン編集:admin.ModelAdmin.inlines の使い方と代替方法
admin.ModelAdmin.inlines
は、Django 管理画面において、関連モデルをインラインで編集するための機能を提供します。
使い方
inlines
属性には、関連モデルの ModelAdmin
クラスをリストまたはタプルで指定します。
class BookAdmin(admin.ModelAdmin):
inlines = [
ChapterAdmin,
AuthorAdmin,
]
この例では、BookAdmin
クラスで ChapterAdmin
と AuthorAdmin
をインライン表示します。
インライン表示のカスタマイズ
inlines
属性に加えて、以下のオプションを使用してインライン表示をカスタマイズできます。
show_change_link
: 変更リンクを表示するかどうかを設定します。max_num
: 最大表示数を設定します。extra
: 空白フォームの数を設定します。fk_name
: 参照する外部キーの名前を設定します。verbose_name_plural
: 複数形のラベルを設定します。verbose_name
: インラインセクションのラベルを設定します。
class BookAdmin(admin.ModelAdmin):
inlines = [
(ChapterAdmin, {'verbose_name': '章', 'verbose_name_plural': '章', 'extra': 2}),
(AuthorAdmin, {'verbose_name': '著者', 'verbose_name_plural': '著者', 'max_num': 3}),
]
利点
- 関連モデル間の関係性を把握しやすいです。
- 複雑な関係性の場合、専用のフォームを作成する必要があります。
- インライン編集は、単純な関係性の場合にのみ適しています。
例1:書籍管理
この例では、書籍、章、著者を管理するモデルと、それぞれの管理画面クラスを定義します。
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=255)
class Chapter(models.Model):
title = models.CharField(max_length=255)
book = models.ForeignKey('Book', on_delete=models.CASCADE)
class Book(models.Model):
title = models.CharField(max_length=255)
author = models.ForeignKey('Author', on_delete=models.CASCADE)
# 管理画面クラス
class BookAdmin(admin.ModelAdmin):
inlines = [
ChapterAdmin,
AuthorAdmin,
]
class ChapterAdmin(admin.ModelAdmin):
pass
class AuthorAdmin(admin.ModelAdmin):
pass
例2:商品管理
この例では、商品、カテゴリ、注文を管理するモデルと、それぞれの管理画面クラスを定義します。
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=255)
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=10, decimal_places=2)
category = models.ForeignKey('Category', on_delete=models.CASCADE)
class Order(models.Model):
customer_name = models.CharField(max_length=255)
order_date = models.DateTimeField(auto_now_add=True)
products = models.ManyToManyField('Product')
# 管理画面クラス
class OrderAdmin(admin.ModelAdmin):
inlines = [
OrderItemInline,
]
class OrderItemInline(admin.TabularInline):
model = Order.products.through
extra = 0
class ProductAdmin(admin.ModelAdmin):
pass
class CategoryAdmin(admin.ModelAdmin):
pass
- 実際の利用では、必要に応じてオプションやメソッドをカスタマイズしてください。
- 上記の例はあくまで基本的な使用方法を示しています。
関連モデルの編集画面へのリンクを表示する
inlines
属性を使用せずに、関連モデルの編集画面へのリンクを表示することができます。
class BookAdmin(admin.ModelAdmin):
list_display = [
'title',
'author',
'chapters_link',
]
@admin.display(link=True)
def chapters_link(self, obj):
return obj.chapter_set.all()
この例では、BookAdmin
クラスの list_display
属性に chapters_link
フィールドを追加しています。このフィールドは、書籍に関連するすべての章へのリンクを表示します。
専用のフォームを作成する
複雑な関係性の場合、inlines
属性ではなく、専用のフォームを作成することができます。
from django import forms
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = ['title', 'author']
class ChapterForm(forms.ModelForm):
class Meta:
model = Chapter
fields = ['title']
class BookChapterForm(forms.ModelForm):
book = forms.ModelChoiceField(queryset=Book.objects.all())
chapters = forms.ModelMultipleChoiceField(queryset=Chapter.objects.all())
class Meta:
model = Chapter
fields = ['book', 'chapters']
この例では、書籍と章の編集用のフォームを作成しています。BookChapterForm
フォームは、書籍と関連する複数の章を選択することができます。
サードパーティ製のライブラリを使用する
Django には、inlines
属性の代替となる機能を提供するサードパーティ製のライブラリがいくつかあります。
これらのライブラリは、より洗練されたインライン編集機能を提供したり、管理画面のデザインをカスタマイズしたりすることができます。
どの方法を選択すべきかは、以下の要素によって異なります。
- 開発者のスキル
- カスタマイズの必要性
- 関係性の複雑さ
シンプルな関係性の場合、inlines
属性で十分です。複雑な関係性の場合、専用のフォームを作成するか、サードパーティ製のライブラリを使用する必要があります。