Help us understand the problem. What is going on with this article?

Django 管理画面逆引きメモ

リスト画面 (Change List View)

表示させる項目を指定

ModelAdmin.list_display = ('hoge',)

Boolを返すModelのカスタムメソッドは直接指定可能。
ついでに __unicode__ or __str__ も指定できるよ。

ModelAdmin.list_display = ('__str__', 'model_custom_method')

詳細画面へのリンクを貼る項目を指定

デフォルトでは一番左側に表示される奴にリンクが付く

ModelAdmin.list_display = ('hoge', 'fuga')
ModelAdmin.list_display_links = ('fuga',)

カスタムした値を表示

ModelAdmin.list_display = ('custom_hoge',)

def custom_hoge(self, obj):
    return u'Hoge'
custom_hoge.short_description = u'表示名'
custom_hoge.allow_tags = True  # htmlタグ許可

ユーザー入力の場合は format_html('hoge') 関数をつかってエスケープしておくとよい。

デフォルトのソート順

ModelAdmin.ordering = ('created_at',)  # 作成時間でソート

カスタムアクション (リストビュー上部のセレクト部分のやつ)

ModelAdmin.actions = ['hoge']  # 定義した関数などをリストアップ
ModelAdmin.actions_on_top = True  # ページ上部に表示
ModelAdmin.actions_on_bottom = True  # ページ下部に表示

カスタムフィールドのソート

Django のソートは全て DB のクエリレベルで行うので、実際にDBにカラムが存在しないフィールドはソートできない。
ただ、カスタムフィールドが、あるフィールドの代理になっているときは、そのフィールド名を指定するとソートできる。

ModelAdmin.list_display = ('number_str',)

# number が数字(int)を返すとする
def number_str(self, obj):
    return str(obj.number)
number_str.admin_order_field = 'number'

list_display でDBにカラムのないカスタムフィールドをソート可能にする方法

StackOverflow Django admin: how to sort by one of the custom list_display fields that has no database field

追加・変更画面

特定のフィールドを更新の対象にしたい

2つの指定方法がある

fields

  1. fields は ModelAdmin.readonly_fields の値も指定できるが、編集はできない
  2. list_display などと違い、Model の field か ModelAdmin.form しか指定できない
ModelAdmin.fields = ('hoge', 'fuga')  # hoge, fuga フィールドのみ追加、更新時の編集対象
ModelAdmin.fields = (('hoge', 'fuga'), 'piyo')  # hoge, fuga が同じ行で表示される

exclude

ModelAdmin.exclude = ('hoge',)  # hoge は編集対象とならない

外部キーの値も、同じ画面で追加/編集できるようにする

# Inline モデルを定義
class SomeForeignKeyModelInline(admin.TabularInline):
    model = SomeForeignKeyModel

# Inline モデルを表示させたいモデルの管理画面に追加
class HogeAdmin(admin.ModelAdmin):
    list_display = ('hoge', 'fuga')
    inlines = [SomeForeignKeyModelInline]

fieldsets オプションでリッチな画面

ModelAdmin.fieldsets = (
    ( '名前', {'オプション名': ('オプション値',)} ),
    (None, {
        'fields': ('hoge', 'fuga')
    }),
)

カスタムフォーム

デフォルトでは ModelForm がよしなに管理画面用のフォームを生成するが、自分でカスタムしたフォームも指定可能

ModelAdmin.form = HogeForm

モデルに定義されていないカスタムのフォームフィールドを管理画面に表示させたい

stackOverflow: django admin - add custom form fields that are not part of the model

既存の自動生成されるフォームをカスタマイズしたい

get_form メソッドでフックする

ModelAdmin.get_form(request, obj=None, **kwargs)

管理画面テンプレートの上書き

設定

管理画面の元テンプレートは contrib/admin/template/admin に格納されている。
上書きする場合は、 TEMPLATE_DIR で設定されているディレクトリに admin/ を追加する。

上書きしたい管理対象を、上記ディレクトリ配下に、 app_name/modelname/ で追加する。
アプリ名以下のテンプレートはアプリ配下の全てのモデルに適応される。
モデル名以下のテンプレートは、そのモデルの管理画面のみ適応される。
ディレクトリ名は全て小文字。

テンプレート作成方針

基本的に必要な部分だけを上書きするほうが効率的。

例:
hoge アプリの fuga モデルの一覧画面を上書きしたいときは
admin/hoge/fuga/change_list.html を作成。

あとは以下のように変更したい {% block %} 上書きしていく。

{% extend 'admin/change_list.html' %}
{% block 'content' %}
<!--
なにか追加したいフォームや変数など
-->
{{ block.super }}
{% endblock 'content' %}

独自機能追加

管理画面に独自機能を追加したい場合、必要になりそうな作業のメモ

URL の追加

独自機能を提供するURLを追加する。
Django管理画面がデフォルトで生成するURLをカスタマイズする必要がある。

get_urls を使う.

from django.conf.urls import url
from django.http import HttpResponse
class HogeAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super(HogeAdmin, self).get_urls()
        my_urls = [
            url(r'^hoge/$', self.admin_site.admin_view(self.hoge), name='hoge'),
        ]
        return my_urls + urls

    def hoge(self, request):
        return HttpResponse('OK')

self.admin_site.admin_view は追加したいビューに、パーミッションのチェックと never_cache を付与するもの。
基本的には、これでラップしておくほうが良い。

return my_url + urls の順番に注意。 my_urls を先にしないと、管理画面標準の URL が優先されて
独自定義した URL のビューまで辿りつけない。

既存管理画面の動作を上書きする

各 View関数の動作をオーバーライドすればよい

class HogeAdmin(admin.ModelAdmin):
    # 一覧画面の動作を上書きする例
    def changelist_view(self, request, extra_context=None):
        extra_context = extra_context or {}
        extra_context['hoge'] = 'hoge'
        return super(HogeAdmin, self).changelist_view(request, extra_context=extra_context)

その他

同一の Model を複数の ModelAdmin で管理する

StackOverflow Multiple ModelAdmins/views for same model in Django admin

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away