はじめに
Djangoチュートリアルもこれで基本的な部分は最後となります。
最後は、アプリの管理ページのカスタマイズについて少し見ていきましょう。
DjangoにはXAMPPでいうphpMyAdminのようにSQLを使わなくてもブラウザでテーブルにレコードの追加や更新・削除を行えるadminフォームという機能があるのでそれをカスタマイズしていきます。
基本的なカスタマイズ
from django.contrib import admin
from .models import Question
class QuestionAdmin(admin.ModelAdmin):
fields = ['pub_date', 'question_text']
admin.site.register(Question, QuestionAdmin)
QuestionAdmin
クラス以下がカスタム内容です。
つまり、モデルごとにクラスを作ることで各テーブルごとにカスタム内容を変えることができるわけです。
fields
でマイグレーションで作成したテーブルの各カラム名を指定します。このとき左から順に実際の表示位置では表示されます。
次にフィールドを増やしてみましょう。
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date']}),
]
fields
をfieldsset
にして(フィールド名, {'fields': ['カラム名']})
と設定してあげるとこのカラムはどの情報だよという表示にすることができます。
例えば ('Date information', {'fields': ['pub_date']})
ならpub_date
はDate information(日付に関する情報)
だよという表示にすることができます。
リレーションしたテーブルのオブジェクトを追加する
from .models import Choice, Question
# ...
admin.site.register(Choice)
Choice
モデルをインポートしadmin.site.register(Choice)
を追加します。
こうすることでChoice
モデルを編集できるようになります。
ですが、今回は1つの質問に対して複数の答えがあるといったリレーションなので、Question
オブジェクトを追加する際にそれに付随してChoice
オブジェクトを追加できた方が都合がいいのでそのように変更してみます。
from django.contrib import admin
from .models import Choice, Question
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
ChoiceInline
クラスでリレーション先のモデルとデータ数を設定します(上の例だと1つのQuestion
オブジェクトに対して、Choice
オブジェクトを3つ分のフィールドが用意される)。
引数にTabularInline
を指定するとphpMyAdmin
のようなテーブル形式の見た目に変更できます。
'classes': ['collapse']
を指定したフィールドは折りたたまれた状態で表示されます。
inlines = [ChoiceInline]
で先程のChoiceInline
クラスを指定します。
モデルのインデックスにあたるページをカスタマイズする
実はデフォルトのままだとモデルのレコードの一覧にあたるページ(DjangoではChange List
と呼ばれるみたいです)にはカラムが1つしか表示されません。
これでは不便なのでレコードのカラムをすべて表示できるようにしましょう。
admin.py
のQuestionAdmin
クラスに下記の項目を追加していきます。
# Change Listで表示するカラムの指定
list_display = ('question_text', 'pub_date', 'was_published_recently')
class Question(models.Model):
# 中略
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
models.py
のwas_published_recently()
メソッドを上記のように修正します。
メソッドに属性をつけることでさらに細かくカスタムすることができます。
例えばshort_description
を指定するとカラムの名前を指定したものに変更する事ができます。
admin_order_field
にカラム名を指定すると、そのカラムに対してソート(フィルター)をブラウザ上で行えるようになります。
boolean
属性を指定するとTrue or False
の代わりに○×のアイコンが表示されます。
was_published_recently
はTrue or False
の値を持つのでその代わりにアイコン表示になるということですね。
では再びadmin.py
に戻ります。
from django.contrib import admin
from .models import Question, Choice
# Register your models here.
class ChoiceInline(admin.TabularInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
list_display = ('question_text', 'pub_date', 'was_published_recently')
fieldsets = [
(None, {'fields': ['question_text']}),
('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
]
inlines = [ChoiceInline]
list_filter = ['pub_date']
search_fields = ['question_text']
admin.site.register(Question, QuestionAdmin)
# admin.site.register(Choice)
list_filter = ['pub_date']
の設定は先程のadmin_order_field
の設定と合わせてフィルターサイドバーを表示するようにする設定です。
search_fields = ['question_text']
は検索ボックスを表示するようにする設定です。
こうすると、Change List
中でこの場合はquestion_text
カラムを検索ボックスに入れた検索語で検索できるようになります。
最後に
これでDjangoチュートリアル全7章完遂です。
しかしここまではあくまで基本で例えばこのチュートリアル1つとっても補足の章としてテストとデプロイ・再利用の章がありますし、この章の管理画面のカスタマイズにしても、テンプレートの使用やCSSの適用、管理機能のさらなる詳細設定など色々ありますのでまだまだやらなければならないことは多いです。
完走した感想はというと、Pythonという言語も含めてDjangoは1からプログラミングを始めた人にとってはやや理解が難しいところがあるとは思いますが、逆に他の言語を習得できている人からすると確かに学習コストを少なく習得できるのかもしれないなという手応えは感じています。
これからチーム開発企画を含めて、自分で制作物を作っていきつつさらに理解を深めていきたいと思います。
参考
[Python] Django 管理サイトのカスタマイズ(表示面)
[Django 管理画面逆引きメモ]https://qiita.com/zenwerk/items/044c149d93db097cdaf8)
Djangoドキュメント