【Django】ModelAdminを使ってadminサイトのチェンジリストをカスタマイズする


投稿日 2019年11月8日 >> 更新日 2023年3月2日

今回はDjangoの管理インターフェイスであるadminサイトの「チェンジリスト」を中心にカスタマイズしていきたいと思います。

ここで明確にしておきたいのですが、「チェンジリスト」とは上図にもあったような保存済みデータがリスト表示されているページです。

なので下図のようなページ内(チェンジフォームもしくわ追加・編集ページ)でのカスタマイズに関してはこちらの「【Django】adminサイトの追加・編集ページのレイアウトをカスタマイズする」をご参照ください。

なお、adminサイトのカラーチェンジやサイト名・タイトル名の変更に関してはこちらで説明しています。

そしてadminサイトを深く詳しく知りたいという方は、Django公式ドキュメントをご参照ください。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python 3.6.8
pip 9.0.1
使用ライブラリ ライセンス
Django==2.2.6 BSD

簡単なブログアプリを作成

簡単な説明ですが、データを表示できるようにモデルを作っておきます。

お好きなモデルを作成してもよいですが、ここではカテゴリーモデルに紐づいたブログモデルであるブログアプリを作成します。

※「view.py」や「urls.py」には手を付けません。

プロジェクトとアプリの作成


$ django-admin startproject project

$ cd project

/project$ python3 manage.py startapp blog

プロジェクトディレクトリ内の「settings.py」の編集

# project/project/settings.py

INSTALLED_APPS = [
    'blog.apps.BlogConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'

アプリディレクトリの「models.py」にてカテゴリーとブログ内容を保存するモデルを作成。

# project/blog/models.py

from django.db import models


class Category(models.Model):
    title = models.CharField('カテゴリー', max_length=20)

    def __str__(self):
        return self.title


class Blog(models.Model):
    title = models.CharField('タイトル', max_length=50)
    text = models.TextField('テキスト')
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    created_at = models.DateField('作成日', auto_now_add=True)
    updated_at = models.DateField('更新日', auto_now=True)

    def __str__(self):
        return self.title

作成したモデルをadminサイトに適用させます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


admin.site.register(Category)
admin.site.register(Blog)

作成したモデルをDjangoに反映させ、adminサイトを使う為にスーパーユーザーを作成します。

# project/

$ python3 manage.py makemigrations blog

$ python3 manage.py migrate

$ python3 manage.py createsuperuser

$ python3 manage.py runserver
127.0.0.1:8000

ブラウザにて「127.0.0.1:8000/admin」へログインすると

アプリ名・モデル名を変更

adminサイト内でローマ字表記されているアプリ名とモデル名を変更していきます。

アプリ名を変更するには、アプリディレクトリ内にある「apps.py」でサブクラスを使用して追記します。

# project/blog/apps.py

from django.apps import AppConfig


class BlogConfig(AppConfig):
    name = 'blog'
    verbose_name = 'ブログアプリ'

そしてモデル名は「models.py」に定義した各モデルに「Metaクラス」を追記してサブクラスを使用します。

# project/blog/models.py

from django.db import models


class Category(models.Model):
    title = models.CharField('カテゴリー', max_length=20)

    def __str__(self):
        return self.title

    """ 追記 """
    class Meta:
        verbose_name = 'カテゴリー'
        verbose_name_plural = 'カテゴリー'


class Blog(models.Model):
    title = models.CharField('タイトル', max_length=50)
    text = models.TextField('テキスト')
    category = models.ForeignKey(Category, on_delete=models.PROTECT)
    created_at = models.DateField('作成日', auto_now_add=True)
    updated_at = models.DateField('更新日', auto_now=True)

    def __str__(self):
        return self.title

    """ 追記 """
    class Meta:
        verbose_name = 'ブログ'
        verbose_name_plural = 'ブログ'

それぞれ指定した名前に表記されます。

チェンジリストをカスタマイズ

ここからは、チェンジリストを中心にカスタマイズをしていきます。

「admin.py」を編集することによりさまざまな操作を行うことができます。

まずはどのように表示されるのか確かめるために、データを保存します。

デフォルトではこのようにさっぱりとしたチェンジリストになっています。

このチェンジリストを「ModelAdminクラス」を使用して、項目の追加や検索フォームなどを追加していきます。

フィールド名を指定して表示させる

「models.py」で定義したBlogモデルのフィールドを指定して、チェンジリストに表示させてみます。

それを行うには、「admin.py」にて表示させたいモデル名で「ModelAdminクラス」を継承するだけで表現することができます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


""" ブログモデルのみ適用 """
class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)    ←追記

「list_display」サブクラスにモデルのフィールド名をリストかタプルで与えると、そのフィールド名が表示されます。

現在タイトルリストにリンク付けがされていますが、「list_display_links」サブクラスを使ってリンク付けの対象を指定できます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


""" ブログモデルのみ適用 """
class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = ('category', 'updated_at')    ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

チェンジリスト内で簡易編集

追加ページにわざわざ飛ばず、タイトル名やカテゴリーをチェンジリストページで変更したい場合は、「list_editable」サブクラスを使用します。

「list_display」サブクラスで指定されたフィールド名しか適応されないので注意しましょう。

先ほど設定した「list_display_links」サブクラスですが、リンク付けされているとエラーとなってしまうので、対象を「None」にしておきます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None      ←変更
    list_editable = ('title', 'category')      ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

チェンジリストの並び順

並び順を操作するには「ordering」サブクラスを使用します。

並び順といっても、番号順や日付順、アルファベット順などさまざまありますが分かりやすいようにタイトル名をアルファベット順に指定したいと思います。

ブログデータを余分に追加し、「ordering」サブクラスを使います。

データを追加

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None
    list_editable = ('title', 'category')
    ordering = ('title',)       ←追記
    # ordering = ('-title')      ←逆の動作


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

セレクトボックスからラジオボタンに変更

現在カテゴリーのリストではセレクトボックスでカテゴリーを選択できるようになっています。

「radio_fields」サブクラスを使うことによってラジオボタンで選択できるようになります。

「radio_fields」サブクラスは、「ForeignKey」もしくわ「choices」が指定されたフィールドで使用することができます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None
    list_editable = ('title', 'category')
    ordering = ('title',)
    radio_fields = {'category': admin.VERTICAL}    ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

上記のコードでは「縦」に並びます。

「HORIZONTAL」を指定すると「横」に並びます。


radio_fields = {"category": admin.HORIZONTAL}

チェンジリストに検索フォームを追加

データが多くなってくると探すのに便利なのが検索フォームです。

検索フォームも「search_fields」サブクラスを使用することによって簡単に追加することができます。

タイトル文とテキスト文を検索できるように指定します。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None
    list_editable = ('title', 'category')
    ordering = ('title',)
    radio_fields = {"category": admin.HORIZONTAL}
    search_fields = ['title', 'text']        ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

アクションバーの配置変更

アクションバーとは下図にあるブログモデル全体に対するセレクトボックスです。

今回は配置場所を指定するだけなので、アクションバーについて色々操作を行いたい場合は、Django公式ドキュメントをご参照ください。

アクションバーは上部と下部に設置することができて、サブクラスでは上部「actions_on_top」、下部「actions_on_bottom」を真偽値で設定することにより表示/非表示とすることができます。

デフォルトとは真逆の設定をしていきます。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None
    list_editable = ('title', 'category')
    ordering = ('title',)
    radio_fields = {"category": admin.HORIZONTAL}
    search_fields = ['title', 'text']
    actions_on_top = False        ←追記
    actions_on_bottom = True      ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

日付ナビゲーションを追加する

最後に下図のような日付ごとにリンク付けされたドリルダウンナビゲーションを追加していきたいと思います。

ドリルダウンナビゲーションとは、ページ内で、リンクなどの項目を選択して大分類から小分類へと対象を絞り込んでいくナビゲーションです。

この設定は「DateField」もしくわ「DateTimeField」を持っているモデルにしか適用されません。

では「date_hierarchy」サブクラスを使用してフィールド名を指定します。

# project/blog/admin.py

from django.contrib import admin
from .models import Category, Blog


class BlogAdmin(admin.ModelAdmin):
    list_display = ('title', 'category', 'updated_at')
    list_display_links = None
    list_editable = ('title', 'category')
    ordering = ('title',)
    radio_fields = {"category": admin.HORIZONTAL} # 横
    search_fields = ['title', 'text']
    actions_on_top = False
    actions_on_bottom = True
    date_hierarchy = 'created_at'       ←追記


admin.site.register(Category)
admin.site.register(Blog, BlogAdmin)

チェンジリストでできることはまだまだありますが、詳しく知りたい方はDjango公式ドキュメントをご参照ください。

そして「チェンジフォームもしくわ追加ページ」の操作も自由に行うことができるので挑戦してみましょう。

それでは以上となります。

最後までご覧いただきありがとうございました。