勉強会用資料です.
django1.8のチュートリアルを辿りつつ説明していきます.
https://docs.djangoproject.com/en/1.8/intro/tutorial02/
日本語の公式ドキュメントはバージョン1.4が最新なので若干違いが有りますが大まかな流れは一緒なので一読するのもいいと思います.
http://django-docs-ja.readthedocs.org/en/latest/intro/tutorial02.html
概要
今回はdjangoの管理サイトについて説明していきます.
djangoには標準で管理サイトが用意されており,スタッフ権限を持つユーザはここからモデルを操作することができます.
djangoが標準で持っているユーザモデルを始め,自分が追加したモデル
(例えばチュートリアルで作成した投票用の2つのモデル)も半自動でそれっぽいページを作ってくれます.
データを登録する,一覧表示する,検索する,のようなデータを扱うだけのwebアプリなら
このページをカスタマイズしていくだけで簡単に作成できます.
スーパーユーザの用意
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#creating-an-admin-user
ソース→add_app_4_database_migration
タグ (変更なし)
管理サイトを触るにはスタッフ権限を持つユーザが必要です.
django用のスーパーユーザはcreatesuperuser
コマンドを使って作成します.
$ ./manage.py createsuperuser
Username (leave blank to use 'shimomura'): admin
Email address:
Password:
Password (again):
Superuser created successfully.
createsuperuserコマンドを実行するとUsername, Email, Passwordを入力するよう求められます.
UsernameはdefaultだとPCのusernameがそのまま入ります.今回はadmin
にしています.
Emailは空でも大丈夫です.
Passwordは同じ文字列を2回入力してください.
最後に Superuser created successfully.
と出ると完了です.
管理サイトにアクセス
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#start-the-development-server
ソース→add_app_4_database_migration
タグ → 954ba86
スーパーユーザを作ったらテスト用サーバを起動させて管理サイトにアクセスしてみましょう.
サーバの起動はrunserver
コマンドです.
$ ./manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
November 05, 2015 - 07:37:15
Django version 1.8.5, using settings 'tutorial.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
この状態でブラウザで
http://localhost:8000/admin/
にアクセスすると以下のようなログイン画面にリダイレクトするはずです.
無事ログインできると以下のような画面になります.
デフォルトでは認証用のモデル(GroupsとUsers)だけ表示されています.
--
日本語化
無事サイトは表示できたと思いますが,ご覧のように管理サイトはデフォルトでは英語です.
英語は嫌なので日本語にしましょう.
djangoはもちろん多言語対応してます.
表示する言語はsettings.pyの103行目付近で定義されています.
デフォルトではen-us
になっているので,これをja
に変更しましょう.
# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'
直したら管理サイトにもう一度アクセスしてみてください.
http://localhost:8000/admin/
無事日本語化されたようです.
投票モデル追加
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#make-the-poll-app-modifiable-in-the-admin
ソース→954ba86
→ 35ec2c6
無事管理サイトは見えたところで,今度は自前のモデルも表示させましょう.
管理サイトに表示するモデルの設定やカスタマイズはapp/admin.py
に記述します.
今回はチュートリアルにならってpollsアプリのQuestionモデルを追加します.
from django.contrib import admin
from .models import Question
admin.site.register(Question)
これで管理サイトで表示されるようになったはずです.
データの追加とカスタマイズ
データの追加
データの追加も試してみましょう.
追加リンクを押すとデータ追加用のフォームが表示されます.
Questionモデルはquestion_text
とpub_date
の2つのフィールドを持っていたので,
フォームの表示にも2つの項目が表示されます.
登録するとQuestion object
というデータが1つできているはずです.
もう一回登録するとQuestion object
が2つ表示されます.
オブジェクト名のカスタマイズ
このままだとなんのデータかわからないので,objectを表す文字列を変更しましょう.
変更の仕方は,変更したいモデルの__str__
メソッド(python2系の場合は__unicode__
)をオーバーライドするだけです.
今回は質問内容を表示させるように修正します.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
モデル名のカスタマイズ
モデル自体を表す文字列(この場合はQuestion)を変えたい場合はMetaクラスで設定します.
verbose_name
でそのモデルを表す名前,
verbose_name_plural
でそのモデルの複数形を表す名前を設定できます.
class Question(models.Model):
class Meta:
verbose_name = '質問'
verbose_name_plural = '質問の複数形'
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
Question
, Questions
が 質問
, 質問の複数形
に変わってるのを確認してください.
並び順のカスタマイズ
デフォルトでは登録の降順(新しいものが上に来る)ようになっていますがこれを公開日(pub_date)の新しいものから並べるように変更してみましょう.
変更はモデルのMetaクラスのordering
プロパティで設定します.
設定値はフィールド名,降順にしたい場合は頭に-
をつけます.
class Question(models.Model):
class Meta:
verbose_name = '質問'
verbose_name_plural = '質問の複数形'
ordering = ['-pub_date']
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
まず質問内容順で並べ,同じ場合は公開日の降順で並べる場合は
ordering = ['question_text', '-pubdate']
のように書きます.
実際に並び変わることを確認してみてください.
--
追加時のフォーム自体をカスタマイズすることも可能です.(2つ下の節で説明します)
本家のチュートリアルではこの後Questionオブジェクトを追加する際の
Formのデザインの変え方を説明していますが,今回は説明を割愛します.
興味のある方は本家のチュートリアルを見てください.
https://docs.djangoproject.com/en/1.8/intro/tutorial02/#customize-the-admin-form
relationのあるオブジェクト
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#adding-related-objects
(途中からInline項目の追加
で説明)
ソース→ 35ec2c6
→ 84f1086
pollsアプリが持っているもう一つのモデルであるChoice
を追加していきます.
このモデルはForeignKey(Questionモデルへのリレーション)を持っていますが,どのように表示されるでしょうか?
まずはadminに表示させるためにpolls/admin.py
を編集してChoiceを追加します.
from django.contrib import admin
from .models import Question
from .models import Choice # ここを追加
admin.site.register(Question)
admin.site.register(Choice) # ここを追加
無事追加されたようです.
ChoiceモデルはMeta設定などをしてないのでそのまま出てますね.
続いて追加画面を見ていきます.
ForeignKeyフィールドの場合,Formではこのようにセレクトリストで表示されます.
右側にある緑色のプラスボタンを押すことでQuestionオブジェクトを新しく作ることもできます.
内容はこんな感じで先ほど作成したQuestionモデルのオブジェクトが入っています.
__str__
を設定していない場合はここで3つともQuestion object
と表示されて悲しいことになります.
もちろんこの選択肢も何を出すかも自由にカスタマイズできます.
並び順はモデルのMetaクラスに設定されているordering
で並び替えられます.
Adminサイト用モデルカスタマイズ
このようにadmin.site.register
関数でモデルを登録するだけで自動的に色々やってくれますが,
少し手を加えるだけでFormの内容変更やリストの表示,検索項目の追加など色々カスタマイズすることができます.
カスタマイズするときはadmin.site.reigster
関数の第2引数にAdminサイトでの振る舞いを記述したクラスを渡します.
このクラスはadmin.ModelAdmin
クラスを継承し,必要な箇所だけ自分でオーバーライドして作ります.
文章だけだとわかりにくいので実際にそれぞれのカスタマイズ例を示していきます.
Inline項目の追加
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#adding-related-objects
ソース→ 84f1086
→e4bacf7
ここまでの例ではQuestionとChoiceを追加したい場合,まず元になるQuestionを作成し,
それをChoiceの追加ページで選択する必要がありました.
ChoiceでいちいちQuestionを選択するのはめんどうですし,選択間違いをする可能性もあります.
そこで便利なのがInlineFormです.これを使えばリレーション元のオブジェクト(この場合はQuestion)と
リレーション先のオブジェクト(この場合はChoice)を同時に作成することができます.
adminサイトの場合,InlineAdminというInline表示用のクラスが用意されています.
今回はStackedInline
クラスを使用します.
修正したソースコードは以下のようになります.
from django.contrib import admin
from .models import Question
from .models import Choice
class ChoiceInline(admin.StackedInline):
model = Choice
extra = 3
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
admin.site.register(Question, QuestionAdmin)
admin.site.register(Choice)
ChoiceInline
, QuestionAdmin
の定義を追加し,Questionを登録する際の第2引数に
QuestionAdmin
を渡すように修正しています.
admin.StackedInline
はStacked形式のInlineを作成するためのベースクラスで,
対象となるモデル(この場合はChoice)と表示数(extra=3)を設定します.
他にも最大数,削除可能かどうかなどを設定できます.
admin.ModelAdmin
は管理サイトでのモデルの振る舞いをカスタマイズするためのクラスです.
今回はinlinesを設定し,オブジェクトの追加,編集時の振る舞いを変更しています.
ここまで変更して,再度管理サイトのQuestionの追加ページ(もしくは編集ページ)にいくと
Choicesを同時に編集できるようになっているのが確認できると思います.
オブジェクト表示のカスタマイズ
ドキュメント→https://docs.djangoproject.com/en/1.8/intro/tutorial02/#customize-the-admin-change-list
ソース→e4bacf7
→7f5128a
登録や編集はいい感じになってきたので,今度は一覧表示をカスタマイズしましょう.
表示を変えるにはadmin.ModelAdmin
を継承して作ったクラス(QuestionAdmin
)にlist_displayを設定します.
...
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
list_display = ('question_text', 'pub_date')
...
殺風景だったリストが少し賑やかになりました.
全てのモデルはdjangoが自動的に主キーを付けてくれます.
ついでなのでそれもつけてみましょう.
...
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
list_display = ('pk', 'question_text', 'pub_date')
...
いい感じですね.
もっとカスタマイズ
本家チュートリアルにならって少し特殊なこともしてみましょう.
list_displayにはフィールドの他にも引数なしのメソッドを設定することができます.
Questionモデルに質問が1日以内に公開されたものか確認するwas_published_recently
メソッドを追加します.
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
...
次にlist_displayにこのメソッドを追加します.
...
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
list_display = ('pk', 'question_text', 'pub_date', 'was_published_recently')
...
ちゃんと見えてますね.
Questionに紐付いているChoiceの数を返すメソッドなどを作ってみるとおもしろいかもしれません.
さらにカスタマイズ
list_displayの対象がメソッドの場合,メソッドに属性を追加することで表示の変更やオーダ条件の設定が可能です.
本家チュートリアルに習ってadmin_order_field
, boolean
, short_description
を設定してみましょう.
...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
was_published_recently.admin_order_field = 'pub_date'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
...
とても良い感じになりました.
admin_order_field
は並び替えをする時にどのフィールドを見るかを設定しています.
この例ではpub_date
フィールドで並び替えています.
この属性を設定することでテーブルのヘッダをクリックできるようになり,並び替えができるようになります.
フィルター,検索追加
最後にフィルターと検索を追加してみます.
例のごとくQuestionAdminにプロパティを設定するだけです.
...
class QuestionAdmin(admin.ModelAdmin):
inlines = [ChoiceInline]
list_display = ('pk', 'question_text', 'pub_date', 'was_published_recently')
list_filter = ['pub_date']
search_fields = ['question_text']
...
こんな感じで簡単にフィルター,検索を追加することができます.
--
[次のチュートリアルへ] (http://qiita.com/maisuto/items/eece9d880d94fd241a0d)