kb84tkhrのブログ

何を書こうか考え中です あ、あと組織とは関係ないってやつです 個人的なやつ

Djangoチュートリアル(13) 管理アプリのカスタマイズ

ここでは、引き続き Web 投票アプリケーションの開発を続け、 チュートリアル その2 で少し触れた、Django が自動生成する管理サイトのカスタマイズに焦点を当てます。

む、ということはもうDjangoのWebアプリを作ることについては完全に理解したと言っても過言ではないということか(違う

チュートリアルに含まれてるってことは管理サイトのカスタマイズも
ごく普通に行われてること、ってことかな
投票アプリがユーザ側だとするとこっちは運用側
実際サービスやるとなったらそういうのもたぶん大事

どれくらいカスタマイズできるんだろう
見かけを変えるくらいはできると思うけど・・・?

編集画面の項目の順番を変更する

class QuestionAdmin(admin.ModelAdmin):
    fields = ['pub_date', 'question_text']

admin.site.register(Question, QuestionAdmin)

項目をグループ化する

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']})
    ]

Questionの編集画面にChoiceも出す
これはやりたかった
できるようになってたんだな

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class QuestionAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['question_text']}),
        ('Date information', {'fields': ['pub_date']})
    ]
    inlines = [ChoiceInline]

からっぽの項目が3つ余分に表示されてて一瞬なんだこれとおもったけど
extra = 3はそういうことだった
項目追加用

StackedInlineTabularInlineに変更すると表形式に
こっちのが見やすい

Questionの一覧画面に表示する項目を追加する

class QuestionAdmin(admin.ModelAdmin):
    ...
    list_display = ('question_text', 'pub_date', 'was_published_recently')

文字列なのに関数を呼び出してるとか中でなにかやってるんだろうなあ
こういうときシンボル型があるといいのかな

was_published_recentlyの表示をカスタマイズ
これはQuestionクラスの定義を修正する

class Question(models.Model):
    ...
    def was_published_recently(self):
        ...
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

フィルター・検索を追加

class QuestionAdmin(admin.ModelAdmin):
    ...
    list_filter = ['pub_date']
    search_fields = ['question_text']

プロジェクトテンプレートのカスタマイズ

カスタマイズするには、デフォルトのテンプレートを自分のディレクトリに
コピーしてきて修正する

まずテンプレートを読むようにする

mysite/templatesディレクトリを作って
mysite/mysite/settings.pyのDIRSに追加

TEMPLATES = [
    {
        ...
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        ...
    },
]

なぜフォルダがmysite/mysite/templatesではないのか

mysite/template/adminに
django/contrib/admin/templates/admin/base_site.htmlをコピーしてくる
こんなファイル

{% extends "admin/base.html" %}

{% block title %}{{ title }} | {{ site_title|default:_('Django site admin') }}{% endblock %}

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ site_header|default:_('Django administration') }}</a></h1>
{% endblock %}

{% block nav-global %}{% endblock %}

djangoディレクトリはimport django; print(django.__path__)で調べる

これをこんな風に書き換えるというように読める(ような気もする

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">Polls Administration</a></h1>
{% endblock %}

extendsとかもなくなっちゃっていいのかな
違う気もするけどとりあえずやってみる

案の定"Polls Administration"としか表示されない
やっぱりbrandingのブロックだけ置き換えるんだな
うんOKOK

なおdjango.contrib.admin.AdminSite.site_headerを書き換えるのが本来のやり方
admin/index.htmlとかをコピーしてきて修正すればほかの画面もカスタマイズできる

投票アプリケーションはそれほど複雑ではないので、カスタムの admin テンプレートは必要ないでしょう。しかしアプリケーションがさらに凝ったものに成長し、何か機能を実現するために標準の admin テンプレートを変更する必要が出てきた場合、 アプリケーションの テンプレートを編集するほうが、 プロジェクト のテンプレートを編集するより賢い選択になるでしょう。

これは、polls/templates/adminにpollsをadminするサイトのテンプレートを置く、ということかな
そういう構成もあるのか

次は何をしましょうか?

PPP3に戻ります!
現在のスタックはこうだっけ?

Djangoチュートリアル
Pythonプロフェッショナルプログラミング
プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
Paiza
Reasoned Schemer

なんでこうなった

Pop!