3.

Django Admin アプリケーション登録完全ガイド(admin.py / ModelAdmin / Inline)

編集
この記事の要点
  • Django Admin はモデルを登録するだけで CRUD 画面が自動生成される強力なバックオフィス機能
  • 基本は admin.pyadmin.site.register(Book)
  • ModelAdminlist_display / list_filter / search_fields / fieldsets をカスタマイズ
  • デコレータ形式 @admin.register(Book) が現代的で読みやすい
  • 前提: INSTALLED_APPSdjango.contrib.adminmigrate 済、createsuperuser 完了、/admin/ URL ルーティング

Django Admin を有効化する全体フロー

Django には、モデルを登録するだけで CRUD 画面が自動生成される管理サイトが同梱されています。SaaS の運用担当が DB を直接いじる代わりに、ブラウザから安全にレコードを編集できるため、社内ツールとして非常に重宝します。

全体フロー
1. INSTALLED_APPS に django.contrib.admin が含まれている
2. urls.py で path('admin/', admin.site.urls) が登録されている
3. python manage.py migrate でテーブルを作成
4. python manage.py createsuperuser で管理者作成
5. アプリの admin.py でモデルを register
6. python manage.py runserver で起動
7. http://localhost:8000/admin/ にアクセス

手順1: settings.py / urls.py の確認

# myproject/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',         # ← これが必要
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'library',                       # ← 自作アプリ
]

# myproject/urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),   # ← これが Admin の入口
]

手順2: マイグレーションと管理者作成

# 初期テーブル作成(auth_user, django_admin_log 等)
python manage.py migrate

# 管理者ユーザー作成
python manage.py createsuperuser
# Username (leave blank to use 'me'): admin
# Email address: admin@example.com
# Password: ********

# 起動
python manage.py runserver
# → http://127.0.0.1:8000/admin/ にアクセス

Django Admin ログイン画面とダッシュボード

手順3: モデルを admin.py に登録(基本)

アプリ配下の admin.py でモデルを register します:

# library/models.py
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    birth_date = models.DateField(null=True, blank=True)

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
    published_at = models.DateField()
    isbn = models.CharField(max_length=13, unique=True)
    is_published = models.BooleanField(default=True)

    def __str__(self):
        return self.title


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

admin.site.register(Author)
admin.site.register(Book)

これだけで /admin/library/book/ に Book 一覧が表示され、追加 / 編集 / 削除が GUI で可能になります。

手順4: ModelAdmin でカスタマイズ

本格運用では一覧表示の列・検索・フィルタ・並び順・編集レイアウトをカスタマイズします:

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

@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
    # 一覧画面の列
    list_display = ('title', 'author', 'published_at', 'is_published')
    list_display_links = ('title',)                  # クリック可能列
    list_filter = ('is_published', 'published_at')   # 右サイドのフィルタ
    search_fields = ('title', 'author__name', 'isbn')
    ordering = ('-published_at',)
    list_per_page = 50

    # 編集画面のレイアウト
    fieldsets = (
        ('基本情報', {
            'fields': ('title', 'author', 'isbn'),
        }),
        ('公開設定', {
            'classes': ('collapse',),
            'fields': ('published_at', 'is_published'),
        }),
    )

    readonly_fields = ('isbn',)
    autocomplete_fields = ('author',)   # オートコンプリート

    # アクション(一覧で選択 → アクション実行)
    actions = ['mark_as_published']

    @admin.action(description='選択した書籍を「公開済み」に変更')
    def mark_as_published(self, request, queryset):
        updated = queryset.update(is_published=True)
        self.message_user(request, f'{updated} 件を公開済みに変更しました')


@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('name', 'birth_date')
    search_fields = ('name',)

ModelAdmin の主要オプション

オプション用途
list_display一覧の列指定
list_display_links編集画面に遷移する列を指定
list_filter右側のフィルタ条件
search_fields上部の検索ボックスの対象列
ordering初期ソート
list_per_page1 ページ件数
readonly_fields編集不可フィールド
fieldsets編集画面のグループ化
autocomplete_fields外部キーをオートコンプリート化
raw_id_fields外部キーを ID 入力+ルックアップ
filter_horizontalManyToMany の左右セレクト UI
actions一括処理アクション
prepopulated_fieldsslug 自動生成
save_on_top編集画面上部にも保存ボタン

Inline で関連モデルを同一画面で編集

# Author 編集画面に Book 一覧を埋め込む
class BookInline(admin.TabularInline):    # or StackedInline
    model = Book
    extra = 1
    fields = ('title', 'isbn', 'published_at', 'is_published')
    show_change_link = True

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    list_display = ('name', 'birth_date')
    inlines = [BookInline]

TabularInline は行形式(テーブル)、StackedInline はスタック形式(縦並び)。1:多 / 多:多 関係の管理で便利です。

複数モデルを一気に登録する書き方

# 簡易: register をループで
from django.contrib import admin
from .models import Author, Book, Publisher, Tag

for model in (Author, Book, Publisher, Tag):
    admin.site.register(model)

# 細かい設定を共通で
class BaseAdmin(admin.ModelAdmin):
    list_per_page = 50
    save_on_top = True

@admin.register(Author, Book, Publisher)
class CommonAdmin(BaseAdmin):
    pass

権限とフィルタリング

class BookAdmin(admin.ModelAdmin):
    list_display = ('title', 'author', 'owner')

    # スーパーユーザー以外は自分が作成したレコードだけ表示
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(owner=request.user)

    # 保存時に owner を自動セット
    def save_model(self, request, obj, form, change):
        if not change:
            obj.owner = request.user
        super().save_model(request, obj, form, change)

    # 削除権限のカスタム
    def has_delete_permission(self, request, obj=None):
        return request.user.is_superuser

運用 Tips

  • 本番では /admin/ を別パス(例: /secret-admin-2024/)に変更し、ブルートフォース対象を狭める
  • Django Axes 等で IP ベースのログイン試行制限
  • 2 要素認証django-otp + django-two-factor-auth
  • 大量データには list_select_relatedraw_id_fields で N+1 / セレクト爆発を回避
  • readonly の計算カラムは @admin.display(description='...') デコレータで日本語ラベル化
  • 変更履歴は django.contrib.admin.LogEntry に保存される → django-simple-history で詳細化

よくあるトラブル

症状原因対処
/admin/ にアクセスすると 404urls.py に未登録path('admin/', admin.site.urls) を追加
ログインできないcreatesuperuser 未実行python manage.py createsuperuser
モデルが Admin に出ないadmin.py 未登録 / アプリ未 INSTALLED_APPS登録 + settings 確認
CSS が崩れる(本番)collectstatic 未実行python manage.py collectstatic
外部キーで matching query does not exist関連レコードが既に削除on_deleteSET_NULL に変更

FAQ

Q: 一般ユーザーにも Admin を触らせていい?
A: Admin はあくまで運用担当向けです。エンドユーザーには通常のビューでフロントを作り、Admin は is_staff ユーザーに限定してください。

Q: 一覧画面が重い
A: list_select_related / list_prefetch_related(DRF 由来の慣用)、または get_queryset 内で select_related() / prefetch_related() を明示。

Q: モバイル対応は?
A: Django 4.x 以降の Admin は基本的にレスポンシブです。さらに作り込むなら django-jazzmindjango-grappelli のテーマを利用。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. ユーザーの作成
  2. Django 管理サイト (Administration) へのアクセス方法
  3. アプリケーションの登録
  4. オブジェクトの操作

最近更新/作成されたページ