Django Adminサイトのカスタマイズ
DjangoのAdminサイトは、開発中にモデルのデータを管理するための強力なツールです。しかし、デフォルトのままでは、プロジェクトの要件やデザインに合わない場合があります。Django Adminサイトは、その柔軟性により、様々な方法でカスタマイズすることが可能です。ここでは、Adminサイトをより便利に、より見やすく、そしてより機能的にするための主要なカスタマイズ方法を解説します。
1. Adminクラスの登録と基本設定
Adminサイトでモデルを管理するには、まずそのモデルを admin.ModelAdmin クラスを介して登録する必要があります。
1.1. 基本的な登録
最も簡単な方法は、 admin.py ファイルに以下のコードを追加することです。
from django.contrib import admin
from .models import YourModel
admin.site.register(YourModel)
1.2. Adminクラスの作成
より高度なカスタマイズを行うためには、 admin.ModelAdmin を継承したカスタムAdminクラスを作成します。
from django.contrib import admin
from .models import YourModel
class YourModelAdmin(admin.ModelAdmin):
pass # ここにカスタマイズ設定を記述
admin.site.register(YourModel, YourModelAdmin)
2. Adminクラスでの表示項目と編集項目の制御
Adminクラスの属性を調整することで、リスト表示や編集フォームの表示項目を細かく制御できます。
2.1. list_display: リスト表示の列を定義
list_display 属性にモデルのフィールド名をタプルで指定することで、Adminサイトのリスト表示に表示する列を定義できます。これにより、 id や created_at のような自動生成されるフィールドや、関連モデルのフィールド( __ を使用)も表示可能です。
class YourModelAdmin(admin.ModelAdmin):
list_display = ('field1', 'field2', 'related_field__name', 'get_status_display')
また、モデルに定義したメソッドを list_display に含めることで、動的な情報を表示することもできます。
class YourModel(models.Model):
# ...
def get_status_display(self):
return dict(self.STATUS_CHOICES)[self.status]
get_status_display.short_description = 'ステータス' # 表示名の変更
2.2. fields と exclude: 編集フォームのフィールドを制御
fields 属性を使用すると、編集フォームに表示するフィールドを明示的に指定できます。 exclude 属性を使用すると、指定したフィールド以外をすべて表示します。
class YourModelAdmin(admin.ModelAdmin):
fields = ('field1', 'field2', 'description') # 指定したフィールドのみ表示
# または
# exclude = ('internal_field', 'auto_generated_field') # 指定したフィールド以外を表示
2.3. readonly_fields: 編集不可能なフィールド
readonly_fields 属性に指定したフィールドは、Adminサイト上で編集できなくなります。これは、自動生成されるフィールドや、ユーザーが直接編集すべきでないフィールドに便利です。
class YourModelAdmin(admin.ModelAdmin):
readonly_fields = ('created_at', 'updated_at')
2.4. list_filter: リスト表示のフィルター
list_filter 属性にフィールド名を指定すると、リスト表示の右側にフィルターサイドバーが表示されます。これにより、特定の条件でデータを絞り込みやすくなります。
class YourModelAdmin(admin.ModelAdmin):
list_filter = ('category', 'is_active')
2.5. search_fields: リスト表示の検索
search_fields 属性にフィールド名を指定すると、リスト表示の上部に検索ボックスが表示されます。指定したフィールドのテキストを検索対象とします。
class YourModelAdmin(admin.ModelAdmin):
search_fields = ('name', 'description')
3. 関連モデルの表示と編集
Django Adminサイトでは、関連するモデルのデータを効率的に表示・編集するための機能が用意されています。
3.1. inlines: 関連オブジェクトの表示と編集
inlines 属性を使用すると、親モデルの編集画面内で、子モデルのオブジェクトを一覧表示し、追加・編集・削除できるようになります。 admin.TabularInline または admin.StackedInline を使用します。
from django.contrib import admin
from .models import ParentModel, ChildModel
class ChildInline(admin.TabularInline): # または admin.StackedInline
model = ChildModel
extra = 1 # 新規追加できるフォームの数
class ParentModelAdmin(admin.ModelAdmin):
inlines = [ChildInline]
admin.site.register(ParentModel, ParentModelAdmin)
TabularInline は表形式で表示し、 StackedInline は積み重ねられた形式で表示します。どちらを選ぶかは、デザインや使いやすさによって判断します。
3.2. ForeignKey と ManyToManyField の設定
ForeignKey や ManyToManyField で関連付けられたフィールドについても、 list_display や search_fields で、関連オブジェクトのフィールドを指定することができます。例えば、 user__username のように __ で連結して指定します。
4. Adminサイトのレイアウトとデザインの変更
Adminサイトの見た目をプロジェクトのブランドイメージに合わせるために、レイアウトやデザインをカスタマイズできます。
4.1. get_readonly_fields, get_list_display などの動的なメソッド
list_display や fields などの属性は、クラス属性として固定するだけでなく、 get_list_display(self, request) のようにメソッドとして定義することも可能です。これにより、ユーザーの権限などに応じて表示項目を動的に変更できます。
4.2. CSSとJavaScriptの追加
AdminサイトにカスタムCSSやJavaScriptを追加することで、より詳細なデザイン調整やインタラクティブな機能を追加できます。
Adminクラスで Media クラスを定義します。
class YourModelAdmin(admin.ModelAdmin):
class Media:
css = {
'all': ('css/admin_custom.css',)
}
js = ('js/admin_custom.js',)
これらのファイルは、 static ディレクトリ内に配置します。ただし、Adminサイト用の静的ファイルは django.contrib.admin.static のパスに配置する必要があるため、 collectstatic コマンドで収集されるように設定する必要があります。
4.3. テンプレートのオーバーライド
Adminサイトの各ページ(リスト表示、詳細表示、変更フォームなど)は、Djangoのテンプレートシステムでレンダリングされています。これらのテンプレートをオーバーライドすることで、HTML構造や表示内容を完全にカスタマイズできます。
templates/admin/ ディレクトリ内に、オーバーライドしたいテンプレートと同じパスとファイル名でカスタムテンプレートを作成します。例えば、 myapp/templates/admin/myapp/yourmodel/change_list.html のように作成します。
5. Adminサイトの認証と権限管理
User モデルや Group モデルをAdminサイトで管理する際に、権限設定は非常に重要です。
5.1. get_permissions, has_add_permission など
Adminクラスに has_add_permission(self, request), has_change_permission(self, request, obj=None), has_delete_permission(self, request, obj=None) などのメソッドを定義することで、特定のユーザーがオブジェクトの追加、変更、削除を行う権限があるかどうかを制御できます。これらのメソッドは、 request.user オブジェクトを使用して、ユーザーの権限をチェックします。
5.2. UserAdmin のカスタマイズ
django.contrib.auth.admin.UserAdmin をカスタマイズすることで、ユーザー管理画面をより詳細に設定できます。例えば、 UserAdmin に list_filter や search_fields を追加したり、 inlines を使用してユーザーに関連する情報を表示したりできます。
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User
class UserAdmin(BaseUserAdmin):
list_filter = ('is_staff', 'is_superuser', 'is_active')
search_fields = ('username', 'first_name', 'last_name', 'email')
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
6. その他の高度なカスタマイズ
6.1. Custom Admin Views
AdminサイトのURLパターンに、独自のビューを追加することができます。これにより、Adminサイト内で特定の処理を行うための専用ページを作成できます。
urls.py に以下のように定義します。
from django.urls import path
from . import views
urlpatterns = [
path('admin/myapp/custom_view/', views.custom_admin_view, name='custom_admin_view'),
]
そして、 views.py でビュー関数を定義します。このビュー関数は django.contrib.admin.AdminSite.admin_view デコレーターでラップすると、Adminサイトの権限チェックを自動的に行なってくれます。
6.2. Admin Site Namespaces
複数のアプリケーションでAdminサイトのURLが競合するのを避けるために、Adminサイトに名前空間を設定できます。 urls.py で admin.site.urls を namespace に含めて定義します。
from django.urls import path, include
urlpatterns = [
path('admin/', include(admin.site.urls), name='admin'),
# または
# path('app1/admin/', include('app1.urls.admin')),
# path('app2/admin/', include('app2.urls.admin')),
]
まとめ
Django Adminサイトのカスタマイズは、プロジェクトの生産性を大幅に向上させることができます。 admin.ModelAdmin の様々な属性を理解し、必要に応じてカスタムAdminクラスを作成することで、リスト表示の最適化、編集フォームの制御、関連モデルの効率的な管理、そしてデザインの統一など、多岐にわたるカスタマイズが可能です。さらに、CSS/JavaScriptの追加やテンプレートのオーバーライド、カスタムビューの作成といった方法を用いることで、Adminサイトをプロジェクト固有のニーズに完全に適合させることができます。
