Djangoの管理画面について
Djangoは、Pythonで開発された人気のあるWebフレームワークで、開発者が効率的にWebアプリケーションを構築できます。Djangoの管理画面は、データベースの管理や操作を容易にするための強力な機能を提供しています。この記事では、管理画面のカスタマイズ可能な機能について、いくつか解説します。
この記事はDjango管理画面カスタムシリーズの1つです。
以下に本シリーズの記事を添付します。
GitHubレポジトリ
ここで解説しているソースコードは、GitHubにて公開しておりますので、気になる方はチェックしてみてください!
Django管理画面のオブジェクト一覧ページのカスタム方法
概略
Djangoフレームワークの管理画面は、デフォルトで多くの機能を提供していますが、プロジェクトに応じてカスタマイズすることがよくあります。この記事では、**django.contrib.admin.ModelAdmin
**クラスを継承して管理画面をカスタマイズする方法について解説します。
機能紹介
1. list_display
管理画面のオブジェクト一覧ページで表示するフィールドをリストもしくはタプルで指定します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author") # タイトルと著者を表示するよう設定
admin.site.register(Blog, BlogAdmin)
すると以下の図のように、一覧ページにtitleとauthorが表示されるようになります。
2. list_filter
管理画面のオブジェクト一覧ページに、指定したフィールドをもとにフィルター機能を追加します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",) # authorでフィルター
admin.site.register(Blog, BlogAdmin)
画面にFILTER欄が追加されました。
testuserでフィルターすると、authorがtestuserのオブジェクトのみ表示できました!
3. search_fields
管理画面のオブジェクト一覧ページに、指定したフィールドをもとに検索ボックスを表示し、検索機能を追加します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",) # titleで検索
admin.site.register(Blog, BlogAdmin)
タイトルに”3”が含まれるオブジェクトを検索すると、無事に検索できました!
4. list_per_page
管理画面のオブジェクト一覧ページのページネーション設定を行います。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
list_per_page = 2 # 1ページあたりに表示するオブジェクト数を指定
admin.site.register(Blog, BlogAdmin)
5. ordering
管理画面のオブジェクト一覧ページのデフォルトの並び順を設定します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", ) # titleの昇順に並び替える(降順にするには"-title"を指定)
admin.site.register(Blog, BlogAdmin)
6. exclude
管理画面の追加・編集フォームから、指定したフィールドを除外します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
exclude = ("body", )
admin.site.register(Blog, BlogAdmin)
excludeに”body”を設定すると、編集画面から、bodyがなくなりました。
7. readonly_fields
管理画面の追加・編集フォームで、指定したフィールドを読み取り専用にします。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
exclude = ("body", )
readonly_fields = ("title", ) # titleを読み取り専用にします
admin.site.register(Blog, BlogAdmin)
8. fields
管理画面の追加・編集フォームで、指定したフィールドのみを表示します。表示順も指定した順になります。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
fields = ("author", "title") # authorとtitleのみを表示します
admin.site.register(Blog, BlogAdmin)
上記設定により、authorとtitleのみが表示されました。
9. fieldsets
管理画面の追加・編集フォームで、フィールドをグループ化して表示します
タプルまたはリストで、フィールドのグループを定義します。各グループはタプルで、最初の要素がグループ名、2番目の要素が辞書で、”fields”キーに表示するフィールド名のタプルまたはリストを指定します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
fieldsets = (
("Blogs", {"fields": ("author", "body")}), # authorとbodyを表示します
)
admin.site.register(Blog, BlogAdmin)
上記の設定により、Blogオブジェクトの編集画面には、authorとbodyのみ表示されるようになりました。
10. forms
管理画面の追加・編集フォームで、指定したフォームクラスを使用します。
カスタムフォームを作成します。今回は、bodyを必須とするフォームを作成します。
from django import forms
from .models import Blog
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = "__all__"
def clean_body(self):
body = self.cleaned_data.get("body")
if not body:
raise forms.ValidationError("Body is required.")
return body
カスタムフォームを作成したら、form = BlogForm
として設定します。
from django.contrib import admin
from .models import Blog
from .forms import BlogForm
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
form = BlogForm # カスタムフォームを設定する
admin.site.register(Blog, BlogAdmin)
Bodyを空にして、SAVEを押してみると、カスタムフォームが設定されていることが確認できました。
11. inlines
管理画面の追加・編集フォームで、関連するモデルのインライン編集フォームを表示します。
ここではユーザーオブジェクトの編集画面から、そのユーザーのブログを編集できるよう設定します。
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from .models import User
from blog.models import Blog
# inline用のBlogクラス
class BlogInline(admin.StackedInline):
model = Blog
extra = 1
class UserAdmin(BaseUserAdmin):
list_display = ("username", "email", "is_superuser")
list_filter = ("username",)
inlines = [BlogInline] # inline設定を追加
fieldsets = (
(None, {"fields": ("username", "email", "password")}),
("Permissions", {
"fields": ("is_superuser", "is_staff", "user_permissions")
}),
)
add_fieldsets = (
(None, {
"classes": ("wide",),
"fields": ("username", "email", "password1", "password2"),
},
),
)
search_fields = ("username", "email")
ordering = ("username", "email")
filter_horizontal = ()
admin.site.register(User, UserAdmin)
上記設定を行った後ユーザーオブジェクトを確認すると、そのユーザーのブログが表示されるようになりました。
12. save_on_top
管理画面の追加・編集フォームで、保存ボタンをページの上部にも表示します。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
save_on_top = True # この設定を追加
admin.site.register(Blog, BlogAdmin)
13. prepopulated_fields
管理画面の追加・編集フォームで、指定したフィールドの値を他のフィールドの値に基づいて自動入力します。例えば、スラッグフィールドの自動生成に便利です。
Blogモデルにスラッグフィールドを作成
from django.db import models
from django.utils.translation import gettext_lazy as _
from account.models import User
class Blog(models.Model):
title = models.CharField(
verbose_name=_("title"),
max_length=50,
blank=False,
null=False)
body = models.TextField(
verbose_name=_("body"),
blank=True,
null=True)
author = models.ForeignKey(
User,
verbose_name=_("author"),
on_delete=models.CASCADE)
# 以下のカラムを作成
slug = models.SlugField(
verbose_name=_("slug"),
unique=True)
created_at = models.DateTimeField(
verbose_name=_("created_at"),
auto_now_add=True)
updated_at = models.DateTimeField(
verbose_name=_("updateded_at"),
auto_now=True
)
blog/admin.pyにprepopulated_fieldsを設定
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
prepopulated_fields = {"slug": ("title",)} # 自動生成用
admin.site.register(Blog, BlogAdmin)
Blog作成画面で、Titleを入力すると、自動で、slugフィールドにtitleの文字列が反映されます。
14. raw_id_fields
管理画面の追加・編集フォームで、指定したフィールドを検索可能な選択ボックスに変更します。大量のリレーションがある場合に便利です。
from django.contrib import admin
from .models import Blog
class BlogAdmin(admin.ModelAdmin):
list_display = ("title", "author")
list_filter = ("author",)
search_fields = ("title",)
ordering = ("title", )
raw_id_fields = ('author',) # 外部キーを指定します
admin.site.register(Blog, BlogAdmin)
これで、Django管理画面でBook
モデルを追加・編集する際に、author
フィールドが検索可能なテキストボックスとして表示されます。Author
のIDを直接入力するか、横にある[検索]アイコンをクリックして別ウィンドウで検索し、関連付けるAuthor
を選択できます。
このように、raw_id_fields
を設定することで、外部キーまたは多対多フィールドを簡単に検索して選択できるようになります。これは、選択可能なオブジェクトが大量に存在する場合に特に便利です。
まとめ
Djangoの管理画面は非常に強力で柔軟な機能を持っており、django.contrib.admin.ModelAdmin
クラスを継承してカスタマイズすることが可能です。
この記事で紹介した機能を用いて、プロジェクトに合わせた管理画面を作成しましょう!
適切なカスタマイズによって、開発者や管理者が効率的にデータを管理できるようになりますね!😊