Django管理サイト—Djangoドキュメント

提供:Dev Guides
< DjangoDjango/docs/3.2.x/ref/contrib/admin/index
移動先:案内検索

Django管理サイト

Djangoの最も強力な部分の1つは、自動管理インターフェースです。 モデルからメタデータを読み取り、信頼できるユーザーがサイトのコンテンツを管理できる、モデル中心の迅速なインターフェイスを提供します。 管理者が推奨する使用法は、組織の内部管理ツールに限定されています。 フロントエンド全体を構築するためのものではありません。

管理者にはカスタマイズ用のフックがたくさんありますが、それらのフックを排他的に使用しようとしないように注意してください。 データベースのテーブルとフィールドの実装の詳細を抽象化する、よりプロセス中心のインターフェイスを提供する必要がある場合は、おそらく独自のビューを作成するときです。

このドキュメントでは、Djangoの管理インターフェースをアクティブ化、使用、およびカスタマイズする方法について説明します。

概要

管理者は、:djadmin: `startproject` で使用されるデフォルトのプロジェクトテンプレートで有効になっています。

デフォルトのプロジェクトテンプレートを使用していない場合の要件は次のとおりです。

  1. 'django.contrib.admin'とその依存関係を追加します- django.contrib.authdjango.contrib.contenttypesdjango.contrib.messages 、および[X143X ] django.contrib.sessions -:setting: `INSTALLED_APPS` 設定に。

  2. を構成します DjangoTemplates あなたのバックエンド :setting: `TEMPLATES` 設定django.template.context_processors.requestdjango.contrib.auth.context_processors.auth 、 とdjango.contrib.messages.context_processors.messagesの中に'context_processors'のオプション :setting: `オプション `

    バージョン3.1での変更: django.template.context_processors.requestは、新しい AdminSite.enable_nav_sidebar をサポートするための要件として'context_processors'オプションに追加されました。

  3. :setting: `MIDDLEWARE` 設定をカスタマイズした場合、 django.contrib.auth.middleware.AuthenticationMiddleware および django.contrib.messages.middleware.MessageMiddleware [X190X ]を含める必要があります。

  4. 管理者のURLをURLconf に接続します。

これらの手順を実行した後、フックしたURL(デフォルトでは/admin/)にアクセスして、管理サイトを使用できるようになります。

ログインするユーザーを作成する必要がある場合は、:djadmin: `createsuperuser` コマンドを使用してください。 デフォルトでは、管理者にログインするには、ユーザーが is_staff 属性をTrueに設定している必要があります。

最後に、アプリケーションのどのモデルを管理インターフェースで編集可能にするかを決定します。 これらのモデルごとに、 ModelAdmin の説明に従って、それらを管理者に登録します。

その他のトピック

も参照してください

本番環境で管理者に関連付けられている静的ファイル(画像、JavaScript、CSS)を提供する方法については、ファイルの提供を参照してください。

問題がありますか? FAQを試してください:管理者


ModelAdminオブジェクト

class ModelAdmin

ModelAdminクラスは、管理インターフェイスでのモデルの表現です。 通常、これらはアプリケーションのadmin.pyという名前のファイルに保存されます。 ModelAdminの例を見てみましょう。

from django.contrib import admin
from myapp.models import Author

class AuthorAdmin(admin.ModelAdmin):
    pass
admin.site.register(Author, AuthorAdmin)

ModelAdminオブジェクトが必要ですか?

前の例では、ModelAdminクラスは(まだ)カスタム値を定義していません。 その結果、デフォルトの管理インターフェースが提供されます。 デフォルトの管理インターフェースに満足している場合は、ModelAdminオブジェクトを定義する必要はまったくありません。ModelAdminの説明を入力せずにモデルクラスを登録できます。 前の例は、次のように簡略化できます。

from django.contrib import admin
from myapp.models import Author

admin.site.register(Author)

registerデコレータ

register(*models, site=django.contrib.admin.sites.site)

ModelAdminクラスを登録するためのデコレータもあります。

from django.contrib import admin
from .models import Author

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    pass

ModelAdminに登録するための1つ以上のモデルクラスが与えられています。 カスタム AdminSite を使用している場合は、siteキーワード引数を使用して渡します。

from django.contrib import admin
from .models import Author, Editor, Reader
from myproject.admin_site import custom_admin_site

@admin.register(Author, Reader, Editor, site=custom_admin_site)
class PersonAdmin(admin.ModelAdmin):
    pass

モデル管理クラスを__init__()メソッドで参照する必要がある場合、このデコレータを使用することはできません。 super(PersonAdmin, self).__init__(*args, **kwargs)super().__init__(*args, **kwargs)を使用できます。


管理ファイルの発見

'django.contrib.admin':setting: `INSTALLED_APPS` 設定に入れると、Djangoは各アプリケーションでadminモジュールを自動的に検索してインポートします。

class apps.AdminConfig
これは、管理者のデフォルトの AppConfig クラスです。 Djangoの起動時に autodiscover()を呼び出します。
class apps.SimpleAdminConfig
このクラスは、 autodiscover()を呼び出さないことを除いて、 AdminConfig と同様に機能します。
default_site
デフォルトの管理サイトのクラスまたはサイトインスタンスを返す呼び出し可能オブジェクトへの点線のインポートパス。 デフォルトは'django.contrib.admin.sites.AdminSite'です。 使用法については、デフォルトの管理サイトのオーバーライドを参照してください。
autodiscover()

この関数は、インストールされている各アプリケーションにadminモジュールをインポートしようとします。 このようなモジュールは、管理者にモデルを登録することが期待されています。

通常、Djangoの起動時に AdminConfig が呼び出すため、この関数を直接呼び出す必要はありません。

カスタムAdminSiteを使用している場合は、すべてのModelAdminサブクラスをコードにインポートし、それらをカスタムAdminSiteに登録するのが一般的です。 その場合、自動検出を無効にするには、:setting: `INSTALLED_APPS` 設定に'django.contrib.admin'の代わりに'django.contrib.admin.apps.SimpleAdminConfig'を配置する必要があります。


ModelAdminオプション

ModelAdminは非常に柔軟性があります。 インターフェイスのカスタマイズを処理するためのいくつかのオプションがあります。 すべてのオプションは、ModelAdminサブクラスで定義されています。

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    date_hierarchy = 'pub_date'
ModelAdmin.actions
変更リストページで利用可能にするアクションのリスト。 詳細については、管理者アクションを参照してください。
ModelAdmin.actions_on_top
ModelAdmin.actions_on_bottom
ページ上のアクションバーを表示する場所を制御します。 デフォルトでは、管理者変更リストはページの上部にアクションを表示します(actions_on_top = True; actions_on_bottom = False)。
ModelAdmin.actions_selection_counter
アクションドロップダウンの横に選択カウンターを表示するかどうかを制御します。 デフォルトでは、管理者変更リストに表示されます(actions_selection_counter = True)。
ModelAdmin.date_hierarchy

date_hierarchyをモデルのDateFieldまたはDateTimeFieldの名前に設定すると、変更リストページにそのフィールドによる日付ベースのドリルダウンナビゲーションが含まれます。

例:

date_hierarchy = 'pub_date'

__ルックアップを使用して、関連するモデルのフィールドを指定することもできます。次に例を示します。

date_hierarchy = 'author__pub_date'

これにより、利用可能なデータに基づいてインテリジェントにデータが入力されます。 すべての日付が1か月の場合、日レベルのドリルダウンのみが表示されます。

ノート

date_hierarchyは、内部で QuerySet.datetimes()を使用します。 タイムゾーンサポートが有効になっている場合のいくつかの注意事項については、ドキュメントを参照してください( :setting: `USE_TZ = True ` )。

ModelAdmin.empty_value_display

この属性は、空のレコードのフィールド(None、空の文字列など)のデフォルトの表示値をオーバーライドします。 デフォルト値は-(ダッシュ)です。 例えば:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    empty_value_display = '-empty-'

AdminSite.empty_value_display を使用して、すべての管理ページのempty_value_displayをオーバーライドすることも、次のような特定のフィールドに対してオーバーライドすることもできます。

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    fields = ('name', 'title', 'view_birth_date')

    @admin.display(empty_value='???')
    def view_birth_date(self, obj):
        return obj.birth_date

バージョン3.2で変更: display()デコレータのempty_value引数は、前の表示関数でempty_value_display属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。

ModelAdmin.exclude

この属性を指定する場合は、フォームから除外するフィールド名のリストにする必要があります。

たとえば、次のモデルについて考えてみましょう。

from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3)
    birth_date = models.DateField(blank=True, null=True)

nameフィールドとtitleフィールドのみを含むAuthorモデルのフォームが必要な場合は、fieldsまたはexcludeのように指定します。これ:

from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    fields = ('name', 'title')

class AuthorAdmin(admin.ModelAdmin):
    exclude = ('birth_date',)

Authorモデルにはnametitlebirth_dateの3つのフィールドしかないため、上記の宣言の結果のフォームにはまったく同じフィールドが含まれます。

ModelAdmin.fields

fieldsオプションを使用して、「追加」ページと「変更」ページのフォームで、使用可能なフィールドのサブセットのみを表示したり、順序を変更したり、行にグループ化したりするなど、簡単なレイアウト変更を行います。 たとえば、 django.contrib.flatpages.models.FlatPage モデルの管理フォームのより単純なバージョンを次のように定義できます。

class FlatPageAdmin(admin.ModelAdmin):
    fields = ('url', 'title', 'content')

上記の例では、フィールドurltitle、およびcontentのみがフォームに順番に表示されます。 fieldsには、 ModelAdmin.readonly_fields で定義された値を含めて、読み取り専用として表示することができます。

より複雑なレイアウトのニーズについては、 fieldsets オプションを参照してください。

fieldsオプションは、呼び出し可能オブジェクトが受け入れられないことを除いて、 list_display と同じタイプの値を受け入れます。 モデルおよびモデル管理メソッドの名前は、 readonly_fields にリストされている場合にのみ使用されます。

同じ行に複数のフィールドを表示するには、それらのフィールドを独自のタプルでラップします。 この例では、urlフィールドとtitleフィールドは同じ行に表示され、contentフィールドはそれらの下の独自の行に表示されます。

class FlatPageAdmin(admin.ModelAdmin):
    fields = (('url', 'title'), 'content')

ノート

このfieldsオプションは、次のセクションで説明するように、 fieldsets オプション内にあるfields辞書キーと混同しないでください。

fieldsオプションも fieldsets オプションも存在しない場合、Djangoはデフォルトで、AutoFieldではなく、editable=Trueを持つ各フィールドを1つに表示します。フィールドセット、フィールドがモデルで定義されているのと同じ順序。

ModelAdmin.fieldsets

fieldsetsを設定して、管理者の「追加」ページと「変更」ページのレイアウトを制御します。

fieldsetsは、2つのタプルのリストであり、各2つのタプルは管理フォームページの<fieldset>を表します。 (<fieldset>はフォームの「セクション」です。)

2つのタプルの形式は(name, field_options)です。ここで、nameはフィールドセットのタイトルを表す文字列であり、field_optionsはリストを含むフィールドセットに関する情報の辞書です。その中に表示されるフィールドの。

django.contrib.flatpages.models.FlatPage モデルから抜粋した完全な例:

from django.contrib import admin

class FlatPageAdmin(admin.ModelAdmin):
    fieldsets = (
        (None, {
            'fields': ('url', 'title', 'content', 'sites')
        }),
        ('Advanced options', {
            'classes': ('collapse',),
            'fields': ('registration_required', 'template_name'),
        }),
    )

これにより、次のような管理ページが作成されます。

[[../File:../../../_images/fieldsets|../../../_images/fieldsets.png]]

fieldsetsオプションも fields オプションも存在しない場合、Djangoはデフォルトで、AutoFieldではなく、editable=Trueを持つ各フィールドを1つに表示します。フィールドセット、フィールドがモデルで定義されているのと同じ順序。

field_optionsディクショナリには、次のキーを含めることができます。

  • fields

    このフィールドセットに表示するフィールド名のタプル。 このキーは必須です。

    例:

    {
    'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
    }

    fields オプションと同様に、同じ行に複数のフィールドを表示するには、それらのフィールドを独自のタプルでラップします。 この例では、first_nameフィールドとlast_nameフィールドが同じ行に表示されます。

    {
    'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
    }

    fieldsには、 readonly_fields で定義された値を含めて、読み取り専用として表示することができます。

    呼び出し可能オブジェクトの名前をfieldsに追加すると、 fields オプションと同じルールが適用されます。呼び出し可能オブジェクトは、 readonly_fields にリストされている必要があります。

  • classes

    フィールドセットに適用する追加のCSSクラスを含むリストまたはタプル。

    例:

    {
    'classes': ('wide', 'extrapretty'),
    }

    デフォルトの管理サイトスタイルシートで定義されている2つの便利なクラスは、collapsewideです。 collapseスタイルのフィールドセットは、管理者で最初に折りたたまれ、小さな「クリックして展開」リンクに置き換えられます。 wideスタイルのフィールドセットには、追加の水平スペースが与えられます。

  • description

    各フィールドセットの上部、フィールドセットの見出しの下に表示されるオプションの追加テキストの文字列。 この文字列は、レイアウトが原因で TabularInline に対してレンダリングされません。

    この値は、管理インターフェイスに表示されるときにではなく HTMLエスケープされることに注意してください。 これにより、必要に応じてHTMLを含めることができます。 または、プレーンテキストと django.utils.html.escape()を使用して、HTMLの特殊文字をエスケープすることもできます。

ModelAdmin.filter_horizontal
デフォルトでは、 ManyToManyField<select multiple>とともに管理サイトに表示されます。 ただし、複数選択ボックスは、多くのアイテムを選択するときに使いにくい場合があります。 このリストに ManyToManyField を追加すると、代わりに、オプション内での検索を可能にする、気の利いた控えめなJavaScript「フィルター」インターフェースが使用されます。 選択されていないオプションと選択されたオプションは、2つのボックスに並んで表示されます。 垂直インターフェースを使用するには、 filter_vertical を参照してください。
ModelAdmin.filter_vertical
filter_horizontal と同じですが、フィルターインターフェイスの垂直表示を使用し、選択されていないオプションのボックスが選択されたオプションのボックスの上に表示されます。
ModelAdmin.form

デフォルトでは、ModelFormがモデルに対して動的に作成されます。 これは、追加/変更ページの両方に表示されるフォームを作成するために使用されます。 独自のModelFormを簡単に提供して、追加/変更ページでのデフォルトのフォーム動作をオーバーライドできます。 または、 ModelAdmin.get_form()メソッドを使用して、まったく新しいフォームを指定するのではなく、デフォルトのフォームをカスタマイズすることもできます。

例については、管理者へのカスタム検証の追加のセクションを参照してください。

ノート

ModelFormMeta.model属性を定義する場合は、Meta.fields属性(またはMeta.exclude属性)も定義する必要があります。 ただし、管理者には独自のフィールド定義方法があるため、Meta.fields属性は無視されます。

ModelFormが管理者のみに使用される場合、ModelAdminが使用する正しいモデルを提供するため、最も簡単な解決策はMeta.model属性を省略することです。 または、Metaクラスのfields = []を設定して、ModelFormの検証を満たすこともできます。

ノート

ModelFormModelAdminの両方でexcludeオプションが定義されている場合は、ModelAdminが優先されます。

from django import forms
from django.contrib import admin
from myapp.models import Person

class PersonForm(forms.ModelForm):

    class Meta:
        model = Person
        exclude = ['name']

class PersonAdmin(admin.ModelAdmin):
    exclude = ['age']
    form = PersonForm

上記の例では、「age」フィールドは除外されますが、「name」フィールドは生成されたフォームに含まれます。

ModelAdmin.formfield_overrides

これは、管理者で使用するためにフィールドオプションの一部をオーバーライドするための手っ取り早い方法を提供します。 formfield_overridesは、フィールドクラスを引数の辞書にマッピングして、構築時にフィールドに渡す辞書です。

それは少し抽象的なので、具体的な例を見てみましょう。 formfield_overridesの最も一般的な使用法は、特定のタイプのフィールドにカスタムウィジェットを追加することです。 したがって、デフォルトの<textarea>の代わりに大きなテキストフィールドに使用したいRichTextEditorWidgetを作成したと想像してください。 これを行う方法は次のとおりです。

from django.contrib import admin
from django.db import models

# Import our custom widget and our model from where they're defined
from myapp.models import MyModel
from myapp.widgets import RichTextEditorWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }

辞書のキーは実際のフィールドクラスであり、文字列ではないことに注意してください。 値は別の辞書です。 これらの引数は、フォームフィールドの__init__()メソッドに渡されます。 詳細については、 Forms API を参照してください。

警告

リレーションフィールドを持つカスタムウィジェットを使用する場合(つまり、 ForeignKey または ManyToManyField )、raw_id_fieldsradio_fields、またはautocomplete_fieldsにそのフィールドの名前が含まれていないことを確認してください。

formfield_overridesでは、raw_id_fieldsradio_fields、またはautocomplete_fieldsが設定されているリレーションフィールドのウィジェットを変更できません。 これは、raw_id_fieldsradio_fields、およびautocomplete_fieldsが独自のカスタムウィジェットを暗示しているためです。

ModelAdmin.inlines
以下の InlineModelAdmin オブジェクト、および ModelAdmin.get_formsets_with_inlines()を参照してください。
ModelAdmin.list_display

list_displayを設定して、管理者の変更リストページに表示されるフィールドを制御します。

例:

list_display = ('first_name', 'last_name')

list_displayを設定しない場合、管理サイトには、各オブジェクトの__str__()表現を表示する単一の列が表示されます。

list_displayで使用できる値は4種類あります。 最も単純なものを除いて、 display()デコレータを使用して、フィールドの表示方法をカスタマイズできます。

  • モデルフィールドの名前。 例えば:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name')
  • 1つの引数、モデルインスタンスを受け入れる呼び出し可能オブジェクト。 例えば:

    @admin.display(description='Name')
    def upper_case_name(obj):
        return ("%s %s" % (obj.first_name, obj.last_name)).upper()
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = (upper_case_name,)
  • 1つの引数であるモデルインスタンスを受け入れるModelAdminメソッドを表す文字列。 例えば:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('upper_case_name',)
    
        @admin.display(description='Name')
        def upper_case_name(self, obj):
            return ("%s %s" % (obj.first_name, obj.last_name)).upper()
  • モデルの属性またはメソッドを表す文字列(必須の引数なし)。 例えば:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(description='Birth decade')
        def decade_born_in(self):
            return '%d’s' % (self.birthday.year // 10 * 10)
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'decade_born_in')

list_displayについて注意すべきいくつかの特別なケース:

  • フィールドがForeignKeyの場合、Djangoは関連オブジェクトの__str__()を表示します。

  • ManyToManyFieldフィールドはサポートされていません。これは、テーブルの行ごとに個別のSQLステートメントを実行する必要があるためです。 それでもこれを実行したい場合は、モデルにカスタムメソッドを指定し、そのメソッドの名前をlist_displayに追加します。 (list_displayのカスタムメソッドの詳細については、以下を参照してください。)

  • フィールドがBooleanFieldの場合、DjangoはTrueFalse、またはNone

  • 指定された文字列がモデルのメソッドModelAdminまたは呼び出し可能である場合、Djangoはデフォルトで出力をHTMLエスケープします。 ユーザー入力をエスケープし、エスケープされていない独自のタグを許可するには、 format_html()を使用します。

    モデルの完全な例を次に示します。

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display
        def colored_name(self):
            return format_html(
                '<span style="color: #{};">{} {}</span>',
                self.color_code,
                self.first_name,
                self.last_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'last_name', 'colored_name')
  • いくつかの例ですでに示したように、呼び出し可能メソッド、モデルメソッド、またはModelAdminメソッドを使用する場合、呼び出し可能オブジェクトを display()デコレータでラップして渡すことで、列のタイトルをカスタマイズできます。 description引数。

    バージョン3.2で変更: display()デコレータのdescription引数は、前の表示関数でshort_description属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。

  • フィールドの値がNone、空の文字列、または要素のない反復可能である場合、Djangoは-(ダッシュ)を表示します。 これは AdminSite.empty_value_display でオーバーライドできます。

    from django.contrib import admin
    
    admin.site.empty_value_display = '(None)'

    ModelAdmin.empty_value_display を使用することもできます。

    class PersonAdmin(admin.ModelAdmin):
        empty_value_display = 'unknown'

    またはフィールドレベルで:

    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'birth_date_view')
    
        @admin.display(empty_value='unknown')
        def birth_date_view(self, obj):
             return obj.birth_date

    バージョン3.2で変更: display()デコレータのempty_value引数は、前の表示関数でempty_value_display属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。

  • 指定された文字列がモデルのメソッド、ModelAdmin、またはTrueFalse、またはNoneを返す呼び出し可能オブジェクトである場合、Djangoはかなり「 display()デコレータでメソッドをラップし、値をTrueに設定してboolean引数を渡す場合は、「はい」、「いいえ」、または「不明」アイコン:

    from django.contrib import admin
    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        @admin.display(boolean=True)
        def born_in_fifties(self):
            return 1950 <= self.birthday.year < 1960
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('name', 'born_in_fifties')

    バージョン3.2で変更: display()デコレータのboolean引数は、前の表示関数でboolean属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。

  • __str__()メソッドは、list_displayで他のモデルメソッドと同じように有効であるため、これを実行してもまったく問題ありません。

    list_display = ('__str__', 'some_other_field')
  • 通常、実際のデータベースフィールドではないlist_displayの要素は、並べ替えに使用できません(Djangoがすべての並べ替えをデータベースレベルで行うため)。

    ただし、list_displayの要素が特定のデータベースフィールドを表す場合は、メソッドで display()デコレータを使用し、ordering引数を渡すことで、この事実を示すことができます。

    from django.contrib import admin
    from django.db import models
    from django.utils.html import format_html
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        @admin.display(ordering='first_name')
        def colored_first_name(self):
            return format_html(
                '<span style="color: #{};">{}</span>',
                self.color_code,
                self.first_name,
            )
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('first_name', 'colored_first_name')

    上記は、管理者でcolored_first_nameで並べ替えようとしたときに、first_nameフィールドで並べ替えるようにDjangoに指示します。

    ordering引数で降順を示すには、フィールド名にハイフンプレフィックスを使用できます。 上記の例を使用すると、これは次のようになります。

    @admin.display(ordering='-first_name')

    ordering引数は、関連するモデルの値で並べ替えるクエリルックアップをサポートします。 この例では、リスト表示に「作成者の名」列が含まれており、名で並べ替えることができます。

    class Blog(models.Model):
        title = models.CharField(max_length=255)
        author = models.ForeignKey(Person, on_delete=models.CASCADE)
    
    class BlogAdmin(admin.ModelAdmin):
        list_display = ('title', 'author', 'author_first_name')
    
        @admin.display(ordering='author__first_name')
        def author_first_name(self, obj):
            return obj.author.first_name

    クエリ式は、ordering引数とともに使用できます。

    from django.db.models import Value
    from django.db.models.functions import Concat
    
    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @admin.display(ordering=Concat('first_name', Value(' '), 'last_name'))
        def full_name(self):
            return self.first_name + ' ' + self.last_name

    バージョン3.2で変更: display()デコレータのordering引数は、前の表示関数でadmin_order_field属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。

  • list_displayの要素もプロパティにすることができます。

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
    
        @property
        @admin.display(
            ordering='last_name',
            description='Full name of the person',
        )
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    
    class PersonAdmin(admin.ModelAdmin):
        list_display = ('full_name',)

    @property@displayより上でなければならないことに注意してください。 display()デコレータを使用するのではなく、ディスプレイ関連の属性を直接設定するという古い方法を使用している場合は、property()関数と not に注意してください。 @propertyデコレータを使用する必要があります。

    def my_property(self):
        return self.first_name + ' ' + self.last_name
    my_property.short_description = "Full name of the person"
    my_property.admin_order_field = 'last_name'
    
    full_name = property(my_property)
  • list_displayのフィールド名は、各<th>要素のcolumn-<field_name>の形式で、HTML出力のCSSクラスとしても表示されます。 これは、たとえばCSSファイルの列幅を設定するために使用できます。

  • Djangoは、list_displayのすべての要素を次の順序で解釈しようとします。

    • モデルのフィールド。

    • 呼び出し可能。

    • ModelAdmin属性を表す文字列。

    • モデル属性を表す文字列。

    たとえば、モデルフィールドおよびModelAdmin属性としてfirst_nameがある場合、モデルフィールドが使用されます。

ModelAdmin.list_display_links

list_display_linksを使用して、 list_display のどのフィールドをオブジェクトの「変更」ページにリンクするかを制御します。

デフォルトでは、変更リストページは、最初の列(list_displayで指定された最初のフィールド)を各アイテムの変更ページにリンクします。 ただし、list_display_linksでは、これを変更できます。

  • リンクをまったく取得しないようにするには、Noneに設定します。

  • 列をリンクに変換するフィールドのリストまたはタプル(list_displayと同じ形式)に設定します。

    1つまたは複数のフィールドを指定できます。 フィールドがlist_displayに表示されている限り、Djangoはリンクされているフィールドの数(または数)を気にしません。 唯一の要件は、list_display_linksをこのように使用する場合は、list_displayを定義する必要があるということです。

この例では、first_nameフィールドとlast_nameフィールドが変更リストページにリンクされます。

class PersonAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'birthday')
    list_display_links = ('first_name', 'last_name')

この例では、変更リストページグリッドにリンクがありません。

class AuditEntryAdmin(admin.ModelAdmin):
    list_display = ('timestamp', 'message')
    list_display_links = None

ModelAdmin.list_editable

list_editableをモデルのフィールド名のリストに設定します。これにより、変更リストページで編集できるようになります。 つまり、list_editableにリストされているフィールドは、変更リストページにフォームウィジェットとして表示され、ユーザーは一度に複数の行を編集および保存できます。

ノート

list_editableは、特定の方法で他のいくつかのオプションと相互作用します。 次のルールに注意する必要があります。

  • list_editableのフィールドは、list_displayにも含まれている必要があります。 表示されていないフィールドは編集できません!

  • list_editablelist_display_linksの両方に同じフィールドをリストすることはできません。フィールドをフォームとリンクの両方にすることはできません。

これらのルールのいずれかが破られた場合、検証エラーが発生します。

ModelAdmin.list_filter

次のスクリーンショットに示すように、list_filterを設定して、管理者の変更リストページの右側のサイドバーでフィルターをアクティブにします。

[[../File:../../../_images/list_filter|../../../_images/list_filter.png]]

list_filterは要素のリストまたはタプルである必要があり、各要素は次のいずれかのタイプである必要があります。

  • フィールド名。指定するフィールドは、BooleanFieldCharFieldDateFieldDateTimeFieldIntegerFieldForeignKeyまたはManyToManyField、例:

    class PersonAdmin(admin.ModelAdmin):
        list_filter = ('is_staff', 'company')

    list_filterのフィールド名は、__ルックアップを使用してリレーションにまたがることもできます(例:)。

    class PersonAdmin(admin.UserAdmin):
        list_filter = ('company__name',)
  • django.contrib.admin.SimpleListFilterから継承するクラス。titleおよびparameter_name属性を提供し、lookupsおよびquerysetメソッドをオーバーライドする必要があります。例えば:

    from datetime import date
    
    from django.contrib import admin
    from django.utils.translation import gettext_lazy as _
    
    class DecadeBornListFilter(admin.SimpleListFilter):
        # Human-readable title which will be displayed in the
        # right admin sidebar just above the filter options.
        title = _('decade born')
    
        # Parameter for the filter that will be used in the URL query.
        parameter_name = 'decade'
    
        def lookups(self, request, model_admin):
            """
            Returns a list of tuples. The first element in each
            tuple is the coded value for the option that will
            appear in the URL query. The second element is the
            human-readable name for the option that will appear
            in the right sidebar.
            """
            return (
                ('80s', _('in the eighties')),
                ('90s', _('in the nineties')),
            )
    
        def queryset(self, request, queryset):
            """
            Returns the filtered queryset based on the value
            provided in the query string and retrievable via
            `self.value()`.
            """
            # Compare the requested value (either '80s' or '90s')
            # to decide how to filter the queryset.
            if self.value() == '80s':
                return queryset.filter(birthday__gte=date(1980, 1, 1),
                                        birthday__lte=date(1989, 12, 31))
            if self.value() == '90s':
                return queryset.filter(birthday__gte=date(1990, 1, 1),
                                        birthday__lte=date(1999, 12, 31))
    
    class PersonAdmin(admin.ModelAdmin):
        list_filter = (DecadeBornListFilter,)

    ノート

    便宜上、HttpRequestオブジェクトはlookupsおよびquerysetメソッドに渡されます。次に例を示します。

    class AuthDecadeBornListFilter(DecadeBornListFilter):
    
        def lookups(self, request, model_admin):
            if request.user.is_superuser:
                return super().lookups(request, model_admin)
    
        def queryset(self, request, queryset):
            if request.user.is_superuser:
                return super().queryset(request, queryset)

    また、便宜上、ModelAdminオブジェクトはlookupsメソッドに渡されます。たとえば、使用可能なデータに基づいてルックアップを行う場合などです。

    class AdvancedDecadeBornListFilter(DecadeBornListFilter):
    
        def lookups(self, request, model_admin):
            """
            Only show the lookups if there actually is
            anyone born in the corresponding decades.
            """
            qs = model_admin.get_queryset(request)
            if qs.filter(birthday__gte=date(1980, 1, 1),
                          birthday__lte=date(1989, 12, 31)).exists():
                yield ('80s', _('in the eighties'))
            if qs.filter(birthday__gte=date(1990, 1, 1),
                          birthday__lte=date(1999, 12, 31)).exists():
                yield ('90s', _('in the nineties'))
  • タプル。最初の要素はフィールド名で、2番目の要素はdjango.contrib.admin.FieldListFilterから継承するクラスです。次に例を示します。

    class PersonAdmin(admin.ModelAdmin):
        list_filter = (
            ('is_staff', admin.BooleanFieldListFilter),
        )

    RelatedOnlyFieldListFilterを使用して、関連するモデルの選択をその関係に関係するオブジェクトに制限できます。

    class BookAdmin(admin.ModelAdmin):
        list_filter = (
            ('author', admin.RelatedOnlyFieldListFilter),
        )

    authorForeignKeyからUserモデルであるとすると、list_filterの選択肢は、すべてのユーザーを一覧表示するのではなく、本を書いたユーザーに限定されます。

    EmptyFieldListFilterを使用して空の値をフィルタリングできます。これは、フィールドに格納できる内容に応じて、空の文字列とnullの両方でフィルタリングできます。

    class BookAdmin(admin.ModelAdmin):
        list_filter = (
            ('title', admin.EmptyFieldListFilter),
        )

    ノート

    FieldListFilter APIは内部と見なされ、変更される可能性があります。

    ノート

    GenericForeignKey フィールドはサポートされていません。

    バージョン3.1の新機能: EmptyFieldListFilterクラスが追加されました。

リストフィルターは通常、フィルターに複数の選択肢がある場合にのみ表示されます。 フィルタのhas_output()メソッドは、フィルタを表示するかどうかを制御します。

リストフィルターをレンダリングするためのカスタムテンプレートを指定することができます。

class FilterWithCustomTemplate(admin.SimpleListFilter):
    template = "custom_template.html"

具体的な例については、Djangoが提供するデフォルトのテンプレート(admin/filter.html)を参照してください。

ModelAdmin.list_max_show_all
list_max_show_allを設定して、「すべて表示」管理者変更リストページに表示できるアイテムの数を制御します。 管理者は、合計結果数がこの設定以下の場合にのみ、変更リストに「すべて表示」リンクを表示します。 デフォルトでは、これは200に設定されています。
ModelAdmin.list_per_page
list_per_pageを設定して、ページ化された各管理者変更リストページに表示されるアイテムの数を制御します。 デフォルトでは、これは100に設定されています。
ModelAdmin.list_select_related

list_select_relatedを設定して、管理者変更リストページでオブジェクトのリストを取得する際に select_related()を使用するようにDjangoに指示します。 これにより、大量のデータベースクエリを節約できます。

値は、ブール値、リスト、またはタプルのいずれかである必要があります。 デフォルトはFalseです。

値がTrueの場合、select_related()が常に呼び出されます。 値がFalseに設定されている場合、Djangoはlist_displayを調べ、ForeignKeyが存在する場合はselect_related()を呼び出します。

よりきめ細かい制御が必要な場合は、list_select_relatedの値としてタプル(またはリスト)を使用してください。 タプルが空の場合、Djangoがselect_relatedを呼び出すことはまったくできなくなります。 その他のタプルは、パラメーターとしてselect_relatedに直接渡されます。 例えば:

class ArticleAdmin(admin.ModelAdmin):
    list_select_related = ('author', 'category')

select_related('author', 'category')を呼び出します。

リクエストに基づいて動的な値を指定する必要がある場合は、 get_list_select_related()メソッドを実装できます。

ノート

ModelAdminは、 select_related()がチェンジリストのQuerySetですでに呼び出されている場合、この属性を無視します。

ModelAdmin.ordering

orderingを設定して、Django管理ビューでオブジェクトのリストを並べ替える方法を指定します。 これは、モデルの ordering パラメーターと同じ形式のリストまたはタプルである必要があります。

これが提供されていない場合、Django管理者はモデルのデフォルトの順序を使用します。

動的な順序を指定する必要がある場合(たとえば、ユーザーや言語に応じて)、 get_ordering()メソッドを実装できます。

順序付けと並べ替えに関するパフォーマンスの考慮事項

結果の決定論的な順序付けを確実にするために、変更リストは、合計順序付けを提供する単一または一意のフィールドのセットが見つからない場合、順序付けにpkを追加します。

たとえば、デフォルトの順序が一意でないnameフィールドによる場合、チェンジリストはnameおよびpkで並べ替えられます。 行が多く、namepkにインデックスがない場合、これはパフォーマンスが低下する可能性があります。

ModelAdmin.paginator
ページ付けに使用されるpaginatorクラス。 デフォルトでは、 django.core.paginator.Paginator が使用されます。 カスタムpaginatorクラスに django.core.paginator.Paginator と同じコンストラクターインターフェイスがない場合は、 ModelAdmin.get_paginator()の実装も提供する必要があります。
ModelAdmin.prepopulated_fields

prepopulated_fieldsを辞書に設定し、フィールド名を事前入力するフィールドにマッピングします。

class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}

設定すると、指定されたフィールドはJavaScriptを使用して、割り当てられたフィールドからデータを入力します。 この機能の主な用途は、1つ以上の他のフィールドからSlugFieldフィールドの値を自動的に生成することです。 生成された値は、ソースフィールドの値を連結し、その結果を有効なスラッグに変換することによって生成されます(例: スペースをダッシュに置き換え、ASCII文字を小文字にします)。

事前入力されたフィールドは、値が保存された後、JavaScriptによって変更されません。 通常、スラッグが変更されることは望ましくありません(スラッグが使用されている場合、オブジェクトのURLが変更される可能性があります)。

prepopulated_fieldsは、DateTimeFieldForeignKeyOneToOneField、およびManyToManyFieldフィールドを受け入れません。

バージョン3.2で変更:古いバージョンでは、生成された値からさまざまな英語のストップワードが削除されます。

ModelAdmin.preserve_filters
デフォルトでは、適用されたフィルターは、オブジェクトを作成、編集、または削除した後、リストビューに保持されます。 この属性をFalseに設定すると、フィルターをクリアできます。
ModelAdmin.radio_fields

デフォルトでは、Djangoの管理者は選択ボックスインターフェースを使用します( )であるフィールドの場合ForeignKeyまたは持っているchoices設定。 radio_fieldsにフィールドが存在する場合、Djangoは代わりにラジオボタンインターフェイスを使用します。 groupPersonモデルのForeignKeyであると仮定します。

class PersonAdmin(admin.ModelAdmin):
    radio_fields = {"group": admin.VERTICAL}

django.contrib.adminモジュールからHORIZONTALまたはVERTICALを使用することを選択できます。

ForeignKeyであるか、choicesが設定されていない限り、radio_fieldsにフィールドを含めないでください。

ModelAdmin.autocomplete_fields

autocomplete_fieldsは、 Select2 オートコンプリート入力に変更するForeignKeyおよび/またはManyToManyFieldフィールドのリストです。

デフォルトでは、管理者はこれらのフィールドに選択ボックスインターフェイス(<select>)を使用します。 ドロップダウンに表示するすべての関連インスタンスを選択するオーバーヘッドを発生させたくない場合があります。

Select2入力はデフォルトの入力に似ていますが、オプションを非同期でロードする検索機能が付属しています。 関連するモデルに多くのインスタンスがある場合、これはより高速でユーザーフレンドリーです。

オートコンプリート検索では search_fields が使用されるため、関連オブジェクトのModelAdminで search_fields を定義する必要があります。

不正なデータ開示を回避するには、オートコンプリートを使用するために、ユーザーは関連オブジェクトに対するviewまたはchange権限を持っている必要があります。

結果の順序付けとページ付けは、関連するModelAdminget_ordering()および get_paginator()メソッドによって制御されます。

次の例では、ChoiceAdminForeignKeyからQuestionへのオートコンプリートフィールドがあります。 結果はquestion_textフィールドでフィルタリングされ、date_createdフィールドで並べ替えられます。

class QuestionAdmin(admin.ModelAdmin):
    ordering = ['date_created']
    search_fields = ['question_text']

class ChoiceAdmin(admin.ModelAdmin):
    autocomplete_fields = ['question']

大規模なデータセットのパフォーマンスに関する考慮事項

ModelAdmin.ordering を使用して注文すると、大きなクエリセットでの並べ替えが遅くなるため、パフォーマンスの問題が発生する可能性があります。

また、検索フィールドにデータベースによってインデックス付けされていないフィールドが含まれている場合、非常に大きなテーブルでパフォーマンスが低下する可能性があります。

そのような場合は、フルテキストのインデックス付き検索を使用して、独自の ModelAdmin.get_search_results()実装を作成することをお勧めします。

デフォルトのページネーターは常にcount()クエリを実行するため、非常に大きなテーブルのPaginatorを変更することもできます。 たとえば、Paginator.countプロパティのデフォルトの実装をオーバーライドできます。

ModelAdmin.raw_id_fields

デフォルトでは、Djangoの管理者は選択ボックスインターフェースを使用します( )であるフィールドの場合ForeignKey。 ドロップダウンに表示する関連するすべてのインスタンスを選択する必要があるというオーバーヘッドを発生させたくない場合があります。

raw_id_fieldsは、ForeignKeyまたはManyToManyFieldのいずれかのInputウィジェットに変更するフィールドのリストです。

class ArticleAdmin(admin.ModelAdmin):
    raw_id_fields = ("newspaper",)

raw_id_fields Inputウィジェットには、フィールドがForeignKeyの場合は主キー、フィールドがManyToManyFieldの場合はカンマ区切りの値のリストが含まれている必要があります。 raw_id_fieldsウィジェットは、フィールドの横に虫眼鏡ボタンを表示します。これにより、ユーザーは値を検索して選択できます。

[[../File:../../../_images/raw_id_fields|../../../_images/raw_id_fields.png]]

ModelAdmin.readonly_fields

デフォルトでは、管理者はすべてのフィールドを編集可能として表示します。 このオプションのフィールド(listまたはtupleである必要があります)は、データをそのまま表示し、編集できません。 また、作成と編集に使用される ModelForm からも除外されます。 ModelAdmin.fields または ModelAdmin.fieldsets を指定する場合、表示するには読み取り専用フィールドが存在する必要があることに注意してください(それ以外の場合は無視されます)。

ModelAdmin.fields または ModelAdmin.fieldsets を介して明示的な順序を定義せずにreadonly_fieldsを使用すると、編集可能なすべてのフィールドの後に最後に追加されます。

読み取り専用フィールドは、モデルのフィールドからのデータを表示できるだけでなく、モデルのメソッドまたはModelAdminクラス自体のメソッドの出力も表示できます。 これは、 ModelAdmin.list_display の動作と非常によく似ています。 これは、管理インターフェースを使用して、編集中のオブジェクトのステータスに関するフィードバックを提供する方法を提供します。次に例を示します。

from django.contrib import admin
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('address_report',)

    # description functions like a model field's verbose_name
    @admin.display(description='Address')
    def address_report(self, instance):
        # assuming get_full_address() returns a list of strings
        # for each line of the address and you want to separate each
        # line by a linebreak
        return format_html_join(
            mark_safe('<br>'),
            '{}',
            ((line,) for line in instance.get_full_address()),
        ) or mark_safe("<span class='errors'>I can't determine this address.</span>")
ModelAdmin.save_as

save_asを設定して、管理者変更フォームで「新規として保存」機能を有効にします。

通常、オブジェクトには、「保存」、「保存して編集を続行」、「保存して別のオブジェクトを追加」の3つの保存オプションがあります。 save_asTrueの場合、[保存して別のオブジェクトを追加]は、既存のオブジェクトを更新するのではなく、新しいオブジェクト(新しいIDで)を作成する[新規として保存]ボタンに置き換えられます。

デフォルトでは、save_asFalseに設定されています。

ModelAdmin.save_as_continue

save_as = True の場合、新しいオブジェクトを保存した後のデフォルトのリダイレクトは、そのオブジェクトの変更ビューになります。 save_as_continue=Falseを設定すると、リダイレクトはチェンジリストビューになります。

デフォルトでは、save_as_continueTrueに設定されています。

ModelAdmin.save_on_top

save_on_topを設定して、管理者変更フォームの上部に保存ボタンを追加します。

通常、保存ボタンはフォームの下部にのみ表示されます。 save_on_topを設定すると、ボタンが上部と下部の両方に表示されます。

デフォルトでは、save_on_topFalseに設定されています。

ModelAdmin.search_fields

search_fieldsを設定して、管理者変更リストページの検索ボックスを有効にします。 これは、誰かがそのテキストボックスで検索クエリを送信するたびに検索されるフィールド名のリストに設定する必要があります。

これらのフィールドは、CharFieldTextFieldなどの何らかのテキストフィールドである必要があります。 ForeignKeyまたはManyToManyFieldで、ルックアップAPIの「フォロー」表記を使用して関連するルックアップを実行することもできます。

search_fields = ['foreign_key__related_fieldname']

たとえば、作成者がいるブログエントリがある場合、次の定義により、作成者の電子メールアドレスでブログエントリを検索できます。

search_fields = ['user__email']

誰かが管理者検索ボックスで検索を行うと、Djangoは検索クエリを単語に分割し、大文字と小文字を区別せずに(:lookup: `icontains` ルックアップを使用して)各単語を含むすべてのオブジェクトを返します。ここで、各単語はsearch_fieldsの少なくとも1つに含まれている必要があります。 たとえば、search_fields['first_name', 'last_name']に設定されていて、ユーザーがjohn lennonを検索した場合、Djangoは次のSQL WHERE句と同等の処理を行います。

WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

検索クエリには、スペースを含む引用句を含めることができます。 たとえば、ユーザーが"john winston"または'john winston'を検索すると、Djangoは次のSQL WHERE句と同等の処理を実行します。

WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')

icontainsをルックアップとして使用したくない場合は、フィールドを追加することで任意のルックアップを使用できます。 たとえば、search_fields['first_name__exact']に設定すると、:lookup: `exact` を使用できます。

フィールドルックアップを指定するためのいくつかの(古い)ショートカットも利用できます。 search_fieldsのフィールドの前に次の文字を付けることができます。これは、フィールドに__<lookup>を追加するのと同じです。

プレフィックス

調べる

^

:lookup: `startswith`

=

:lookup: `iexact`

@

:lookup: `search`

なし

:lookup: `icontains`

検索をカスタマイズする必要がある場合は、 ModelAdmin.get_search_results()を使用して、追加または代替の検索動作を提供できます。

バージョン3.2で変更:スペースを含む引用句に対する検索のサポートが追加されました。

ModelAdmin.show_full_result_count

show_full_result_countを設定して、フィルタリングされた管理ページにオブジェクトの全数を表示するかどうかを制御します(例: 99 results (103 total))。 このオプションがFalseに設定されている場合、代わりに99 results (Show all)のようなテキストが表示されます。

デフォルトのshow_full_result_count=Trueは、テーブルでフルカウントを実行するクエリを生成します。これは、テーブルに多数の行が含まれている場合、コストがかかる可能性があります。

ModelAdmin.sortable_by

デフォルトでは、変更リストページでは、すべてのモデルフィールド(および display()デコレータのordering引数を使用する呼び出し可能オブジェクトまたはadmin_order_field属性を持つ呼び出し可能オブジェクト)で並べ替えることができます。 list_display 内。

一部の列の並べ替えを無効にする場合は、sortable_byをコレクションに設定します(例: ソート可能にする list_display のサブセットのlisttuple、またはset)。 空のコレクションは、すべての列の並べ替えを無効にします。

このリストを動的に指定する必要がある場合は、代わりに get_sortable_by()メソッドを実装してください。

ModelAdmin.view_on_site

view_on_siteを設定して、「サイトで表示」リンクを表示するかどうかを制御します。 このリンクをクリックすると、保存されたオブジェクトを表示できるURLに移動します。

この値は、ブールフラグまたは呼び出し可能のいずれかです。 True(デフォルト)の場合、オブジェクトの get_absolute_url()メソッドを使用してURLが生成されます。

モデルに get_absolute_url()メソッドがあり、[サイトで表示]ボタンを表示したくない場合は、view_on_siteFalseに設定するだけです。

from django.contrib import admin

class PersonAdmin(admin.ModelAdmin):
    view_on_site = False

呼び出し可能の場合は、モデルインスタンスをパラメータとして受け入れます。 例えば:

from django.contrib import admin
from django.urls import reverse

class PersonAdmin(admin.ModelAdmin):
    def view_on_site(self, obj):
        url = reverse('person-detail', kwargs={'slug': obj.slug})
        return 'https://example.com' + url

カスタムテンプレートオプション

管理テンプレートのオーバーライドセクションでは、デフォルトの管理テンプレートをオーバーライドまたは拡張する方法について説明します。 ModelAdmin ビューで使用されるデフォルトのテンプレートを上書きするには、次のオプションを使用します。

ModelAdmin.add_form_template
add_view()によって使用されるカスタムテンプレートへのパス。
ModelAdmin.change_form_template
change_view()によって使用されるカスタムテンプレートへのパス。
ModelAdmin.change_list_template
changelist_view()によって使用されるカスタムテンプレートへのパス。
ModelAdmin.delete_confirmation_template
delete_view()が、1つ以上のオブジェクトを削除するときに確認ページを表示するために使用するカスタムテンプレートへのパス。
ModelAdmin.delete_selected_confirmation_template
delete_selectedアクションメソッドで使用されるカスタムテンプレートへのパス。1つ以上のオブジェクトを削除するときに確認ページを表示します。 アクションドキュメントを参照してください。
ModelAdmin.object_history_template
history_view()によって使用されるカスタムテンプレートへのパス。
ModelAdmin.popup_response_template
response_add()response_change()、および response_delete()によって使用されるカスタムテンプレートへのパス。


ModelAdminメソッド

警告

ModelAdmin.save_model()および ModelAdmin.delete_model()をオーバーライドする場合、コードはオブジェクトを保存/削除する必要があります。 これらは拒否を目的としたものではなく、追加の操作を実行できるようにします。


ModelAdmin.save_model(request, obj, form, change)

save_modelメソッドには、HttpRequest、モデルインスタンス、ModelFormインスタンス、およびオブジェクトを追加するか変更するかに基づくブール値が与えられます。 このメソッドをオーバーライドすると、保存前または保存後の操作を実行できます。 super().save_model()を呼び出し、 Model.save()を使用してオブジェクトを保存します。

たとえば、保存する前にrequest.userをオブジェクトにアタッチするには:

from django.contrib import admin

class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super().save_model(request, obj, form, change)
ModelAdmin.delete_model(request, obj)
delete_modelメソッドには、HttpRequestとモデルインスタンスが与えられます。 このメソッドをオーバーライドすると、削除前または削除後の操作を実行できます。 super().delete_model()を呼び出して、 Model.delete()を使用してオブジェクトを削除します。
ModelAdmin.delete_queryset(request, queryset)
delete_queryset()メソッドには、削除するオブジェクトのHttpRequestQuerySetが与えられます。 このメソッドをオーバーライドして、「選択したオブジェクトの削除」アクションの削除プロセスをカスタマイズします。
ModelAdmin.save_formset(request, form, formset, change)

save_formsetメソッドには、HttpRequest、親ModelFormインスタンス、および親オブジェクトを追加するか変更するかに基づくブール値が与えられます。

たとえば、request.userを変更された各フォームセットモデルインスタンスにアタッチするには、次のようにします。

class ArticleAdmin(admin.ModelAdmin):
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.user = request.user
            instance.save()
        formset.save_m2m()

フォームセットへのオブジェクトの保存も参照してください。

ModelAdmin.get_ordering(request)

get_orderingメソッドは、パラメーターとしてrequestを取り、 ordering 属性と同様の順序付けに対してlistまたはtupleを返すことが期待されます。 。 例えば:

class PersonAdmin(admin.ModelAdmin):

    def get_ordering(self, request):
        if request.user.is_superuser:
            return ['name', 'rank']
        else:
            return ['name']
ModelAdmin.get_search_results(request, queryset, search_term)

get_search_resultsメソッドは、表示されるオブジェクトのリストを、指定された検索語に一致するオブジェクトに変更します。 リクエスト、現在のフィルタを適用するクエリセット、およびユーザー提供の検索語を受け入れます。 検索を実装するために変更されたクエリセットを含むタプルと、結果に重複が含まれる可能性があるかどうかを示すブール値を返します。

デフォルトの実装では、 ModelAdmin.search_fields で指定されたフィールドが検索されます。

このメソッドは、独自のカスタム検索メソッドでオーバーライドされる場合があります。 たとえば、整数フィールドで検索したり、SolrやHaystackなどの外部ツールを使用したりできます。 検索メソッドによって実装されたクエリセットの変更によって結果に重複が生じる可能性があるかどうかを確認し、戻り値の2番目の要素にTrueを返す必要があります。

たとえば、nameageで検索するには、次のように使用できます。

class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age')
    search_fields = ('name',)

    def get_search_results(self, request, queryset, search_term):
        queryset, may_have_duplicates = super().get_search_results(
            request, queryset, search_term,
        )
        try:
            search_term_as_int = int(search_term)
        except ValueError:
            pass
        else:
            queryset |= self.model.objects.filter(age=search_term_as_int)
        return queryset, may_have_duplicates

この実装は、search_fields = ('name', '=age')よりも効率的であり、PostgreSQLの... OR UPPER("polls_choice"."votes"::text) = UPPER('4')のように、数値フィールドの文字列比較が行われます。

ModelAdmin.save_related(request, form, formsets, change)
save_relatedメソッドには、HttpRequest、親ModelFormインスタンス、インラインフォームセットのリスト、および親が追加されているか変更されているかに基づくブール値が与えられます。 ここでは、親に関連するオブジェクトに対して、保存前または保存後の操作を実行できます。 この時点で、親オブジェクトとそのフォームはすでに保存されていることに注意してください。
ModelAdmin.get_autocomplete_fields(request)
get_autocomplete_fields()メソッドにはHttpRequestが与えられ、上記のオートコンプリートウィジェットで表示されるフィールド名のlistまたはtupleを返すことが期待されます。 ModelAdmin.autocomplete_fields セクションにあります。
ModelAdmin.get_readonly_fields(request, obj=None)
get_readonly_fieldsメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、listまたはtuple
ModelAdmin.get_prepopulated_fields(request, obj=None)
get_prepopulated_fieldsメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、 [を返すことが期待されます。 X137X]、上記の ModelAdmin.prepopulated_fields セクションで説明されています。
ModelAdmin.get_list_display(request)
get_list_displayメソッドにはHttpRequestが与えられ、上記のようにチェンジリストビューに表示されるフィールド名のlistまたはtupleを返すことが期待されます。 ModelAdmin.list_display セクションにあります。
ModelAdmin.get_list_display_links(request, list_display)
get_list_display_linksメソッドには、HttpRequestと、 ModelAdmin.get_list_display()によって返されるlistまたはtupleが与えられます。 ModelAdminで説明されているように、変更ビューにリンクされる変更リストのフィールド名のNoneまたはlistまたはtupleのいずれかを返すことが期待されます。 .list_display_links セクション。
ModelAdmin.get_exclude(request, obj=None)
get_excludeメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、フィールドのリストを返すことが期待されます。 ModelAdmin.exclude で説明されているように。
ModelAdmin.get_fields(request, obj=None)
get_fieldsメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、フィールドのリストを返すことが期待されます。上記の ModelAdmin.fields セクションで説明したように。
ModelAdmin.get_fieldsets(request, obj=None)
get_fieldsetsメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、2つのリストを返すことが期待されます-タプル。上記の ModelAdmin.fieldsets セクションで説明したように、各2タプルは管理フォームページの<fieldset>を表します。
ModelAdmin.get_list_filter(request)
get_list_filterメソッドにはHttpRequestが与えられ、 list_filter 属性と同じ種類のシーケンスタイプを返すことが期待されます。
ModelAdmin.get_list_select_related(request)
get_list_select_relatedメソッドにはHttpRequestが与えられ、 ModelAdmin.list_select_related と同様にブール値またはリストを返す必要があります。
ModelAdmin.get_search_fields(request)
get_search_fieldsメソッドにはHttpRequestが与えられ、 search_fields 属性と同じ種類のシーケンスタイプを返すことが期待されます。
ModelAdmin.get_sortable_by(request)

get_sortable_by()メソッドはHttpRequestに渡され、コレクションを返すことが期待されます(例: 変更リストページでソート可能なフィールド名のlisttuple、またはset)。

デフォルトの実装は、設定されている場合は sortable_by を返し、それ以外の場合は get_list_display()に従います。

たとえば、1つ以上の列がソート可能にならないようにするには:

class PersonAdmin(admin.ModelAdmin):

    def get_sortable_by(self, request):
        return {*self.get_list_display(request)} - {'rank'}
ModelAdmin.get_inline_instances(request, obj=None)

get_inline_instancesメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、listまたはtuple。 たとえば、次の例では、追加、変更、削除、および表示のアクセス許可に基づくデフォルトのフィルタリングなしでインラインが返されます。

class MyModelAdmin(admin.ModelAdmin):
    inlines = (MyInline,)

    def get_inline_instances(self, request, obj=None):
        return [inline(self.model, self.admin_site) for inline in self.inlines]

このメソッドをオーバーライドする場合は、返されるインラインが inlines で定義されたクラスのインスタンスであることを確認してください。そうしないと、関連オブジェクトを追加するときに「BadRequest」エラーが発生する可能性があります。

ModelAdmin.get_inlines(request, obj)
get_inlinesメソッドには、編集中のHttpRequestobj(または追加フォームのNone)が与えられ、反復可能なインラインを返すことが期待されます。 ModelAdmin.inlines で指定する代わりに、このメソッドをオーバーライドして、リクエストまたはモデルインスタンスに基づいてインラインを動的に追加できます。
ModelAdmin.get_urls()

ModelAdminget_urlsメソッドは、URLconfと同じ方法で、そのModelAdminに使用されるURLを返します。 したがって、 URLディスパッチャーに記載されているようにそれらを拡張できます。

from django.contrib import admin
from django.template.response import TemplateResponse
from django.urls import path

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.my_view),
        ]
        return my_urls + urls

    def my_view(self, request):
        # ...
        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
           key=value,
        )
        return TemplateResponse(request, "sometemplate.html", context)

管理レイアウトを使用する場合は、admin/base_site.htmlから拡張します。

{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}

ノート

カスタムパターンは通常の管理URLのに含まれていることに注意してください。管理URLパターンは非常に寛容で、ほぼすべてに一致するため、通常、組み込みのURLの前にカスタムURLを追加することをお勧めします。

この例では、my_view/admin/myapp/mymodel/my_view/でアクセスされます(管理URLが/admin/に含まれていると仮定します)。

ただし、上記で登録したself.my_view関数には、次の2つの問題があります。

  • 権限チェックは ' 実行されないため、一般の人がアクセスできます。

  • キャッシュを防ぐためのヘッダーの詳細は提供されません。 これは、ページがデータベースからデータを取得し、キャッシュミドルウェアがアクティブな場合、ページに古い情報が表示される可能性があることを意味します。

これは通常あなたが望むものではないので、Djangoはパーミッションをチェックしてビューをキャッシュ不可としてマークするための便利なラッパーを提供します。 このラッパーはAdminSite.admin_view()(つまり、 ModelAdminインスタンス内のself.admin_site.admin_view); そのようにそれを使用してください:

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.admin_site.admin_view(self.my_view))
        ]
        return my_urls + urls

上記の5行目の折り返しビューに注目してください。

path('my_view/', self.admin_site.admin_view(self.my_view))

このラッピングは、self.my_viewを不正アクセスから保護し、 django.views.decorators.cache.never_cache()デコレータを適用して、キャッシュミドルウェアがアクティブな場合にキャッシュされないようにします。

ページがキャッシュ可能であるが、それでもパーミッションチェックを実行したい場合は、cacheable=True引数をAdminSite.admin_view()に渡すことができます。

path('my_view/', self.admin_site.admin_view(self.my_view, cacheable=True))

ModelAdminビューにはmodel_admin属性があります。 他のAdminSiteビューには、admin_site属性があります。

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

管理者の追加および変更ビューで使用する ModelForm クラスを返します。 add_view()および change_view()を参照してください。

基本実装では、 modelform_factory()を使用して form をサブクラス化し、 fieldsexclude などの属性で変更します。 したがって、たとえば、スーパーユーザーに追加のフィールドを提供したい場合は、次のように別の基本形式に交換できます。

class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = MySuperuserForm
        return super().get_form(request, obj, **kwargs)

カスタム ModelForm クラスを直接返すこともできます。

ModelAdmin.get_formsets_with_inlines(request, obj=None)

管理者がビューを追加および変更する際に使用する(FormSetInlineModelAdmin )ペアを生成します。

たとえば、変更ビューでのみ特定のインラインを表示する場合は、次のようにget_formsets_with_inlinesをオーバーライドできます。

class MyModelAdmin(admin.ModelAdmin):
    inlines = [MyInline, SomeOtherInline]

    def get_formsets_with_inlines(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if not isinstance(inline, MyInline) or obj is not None:
                yield inline.get_formset(request, obj), inline
ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs)

ModelAdminformfield_for_foreignkeyメソッドを使用すると、外部キーフィールドのデフォルトのフォームフィールドをオーバーライドできます。 たとえば、ユーザーに基づいてこの外部キーフィールドのオブジェクトのサブセットを返すには、次のようにします。

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "car":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

これは、HttpRequestインスタンスを使用してCar外部キーフィールドをフィルタリングし、Userインスタンスが所有する車のみを表示します。

より複雑なフィルターの場合は、ModelForm.__init__()メソッドを使用して、モデルのinstanceに基づいてフィルター処理できます(関係を処理するフィールドを参照)。 例えば:

class CountryAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['capital'].queryset = self.instance.cities.all()

class CountryAdmin(admin.ModelAdmin):
    form = CountryAdminForm
ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs)

formfield_for_foreignkeyメソッドと同様に、formfield_for_manytomanyメソッドをオーバーライドして、多対多フィールドのデフォルトのフォームフィールドを変更できます。 たとえば、所有者が複数の車を所有でき、車が複数の所有者に属することができる場合(多対多の関係)、Car外部キーフィールドをフィルタリングして、Userが所有する車のみを表示できます。 ]:

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "cars":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_manytomany(db_field, request, **kwargs)
ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs)

formfield_for_foreignkeyおよびformfield_for_manytomanyメソッドと同様に、formfield_for_choice_fieldメソッドをオーバーライドして、選択肢を宣言したフィールドのデフォルトのフォームフィールドを変更できます。 たとえば、スーパーユーザーが利用できる選択肢が通常のスタッフが利用できる選択肢と異なる場合は、次のように進めることができます。

class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_choice_field(self, db_field, request, **kwargs):
        if db_field.name == "status":
            kwargs['choices'] = (
                ('accepted', 'Accepted'),
                ('denied', 'Denied'),
            )
            if request.user.is_superuser:
                kwargs['choices'] += (('ready', 'Ready for deployment'),)
        return super().formfield_for_choice_field(db_field, request, **kwargs)

ノート

フォームフィールドに設定されたchoices属性は、フォームフィールドのみに制限されます。 モデルの対応するフィールドに選択肢が設定されている場合、フォームに提供される選択肢はそれらの選択肢の有効なサブセットである必要があります。そうでない場合、保存前にモデル自体が検証されると、フォームの送信は ValidationError で失敗します。

ModelAdmin.get_changelist(request, **kwargs)
リストに使用するChangelistクラスを返します。 デフォルトでは、django.contrib.admin.views.main.ChangeListが使用されます。 このクラスを継承することで、リストの動作を変更できます。
ModelAdmin.get_changelist_form(request, **kwargs)

チェンジリストページのFormsetで使用する ModelForm クラスを返します。 カスタムフォームを使用するには、次に例を示します。

from django import forms

class MyForm(forms.ModelForm):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_form(self, request, **kwargs):
        return MyForm

ノート

ModelFormMeta.model属性を定義する場合は、Meta.fields属性(またはMeta.exclude属性)も定義する必要があります。 ただし、ModelAdminはこの値を無視し、 ModelAdmin.list_editable 属性でオーバーライドします。 ModelAdminは使用する正しいモデルを提供するため、最も簡単な解決策はMeta.model属性を省略することです。

ModelAdmin.get_changelist_formset(request, **kwargs)

list_editable が使用されている場合、チェンジリストページで使用する ModelFormSet クラスを返します。 カスタムフォームセットを使用するには、次に例を示します。

from django.forms import BaseModelFormSet

class MyAdminFormSet(BaseModelFormSet):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_formset(self, request, **kwargs):
        kwargs['formset'] = MyAdminFormSet
        return super().get_changelist_formset(request, **kwargs)
ModelAdmin.lookup_allowed(lookup, value)

チェンジリストページのオブジェクトは、URLのクエリ文字列からのルックアップでフィルタリングできます。 たとえば、 list_filter は次のように機能します。 ルックアップは、 QuerySet.filter()で使用されているものと似ています(例: [email protected])。 クエリ文字列のルックアップはユーザーが操作できるため、不正なデータの漏洩を防ぐためにサニタイズする必要があります。

lookup_allowed()メソッドには、クエリ文字列からのルックアップパスが与えられます(例: 'user__email')および対応する値(例: '[email protected]')、パラメータを使用したチェンジリストのQuerySetのフィルタリングが許可されているかどうかを示すブール値を返します。 lookup_allowed()Falseを返す場合、DisallowedModelAdminLookupSuspiciousOperation のサブクラス)が発生します。

デフォルトでは、lookup_allowed()は、モデルのローカルフィールド、 list_filter で使用されるフィールドパス( get_list_filter()からのパスは除く)、およびに必要なルックアップへのアクセスを許可します。 ] limit_choices_to は、 raw_id_fields で正しく機能します。

このメソッドをオーバーライドして、 ModelAdmin サブクラスで許可されるルックアップをカスタマイズします。

ModelAdmin.has_view_permission(request, obj=None)

objの表示が許可されている場合は、Trueを返す必要があります。それ以外の場合は、Falseを返します。 objがNoneの場合、TrueまたはFalseを返して、このタイプのオブジェクトの表示が一般に許可されているかどうかを示す必要があります(たとえば、Falseは解釈されます)現在のユーザーがこのタイプのオブジェクトを表示することを許可されていないことを意味します)。

ユーザーが「変更」または「表示」権限を持っている場合、デフォルトの実装はTrueを返します。

ModelAdmin.has_add_permission(request)
オブジェクトの追加が許可されている場合はTrueを返し、許可されていない場合はFalseを返す必要があります。
ModelAdmin.has_change_permission(request, obj=None)
objの編集が許可されている場合は、Trueを返し、それ以外の場合はFalseを返す必要があります。 objNoneの場合、TrueまたはFalseを返して、このタイプのオブジェクトの編集が一般に許可されているかどうかを示す必要があります(例: [ X151X]は、現在のユーザーがこのタイプのオブジェクトを編集することを許可されていないことを意味すると解釈されます)。
ModelAdmin.has_delete_permission(request, obj=None)
objの削除が許可されている場合は、Trueを返す必要があります。それ以外の場合は、Falseを返します。 objNoneの場合、TrueまたはFalseを返して、このタイプのオブジェクトの削除が一般に許可されているかどうかを示す必要があります(例: [X149X ]は、現在のユーザーがこのタイプのオブジェクトを削除することを許可されていないことを意味すると解釈されます)。
ModelAdmin.has_module_permission(request)
管理インデックスページにモジュールを表示し、モジュールのインデックスページへのアクセスが許可されている場合は、Trueを返す必要があります。それ以外の場合は、Falseを返します。 デフォルトで User.has_module_perms()を使用します。 これをオーバーライドしても、ビューへのアクセス、ビューの追加、変更、削除、 has_view_permission()has_add_permission()has_change_permission()、および[そのためには、X183X] has_delete_permission()を使用する必要があります。
ModelAdmin.get_queryset(request)

ModelAdminget_querysetメソッドは、管理サイトで編集できるすべてのモデルインスタンスの QuerySet を返します。 このメソッドをオーバーライドする1つの使用例は、ログインしたユーザーが所有するオブジェクトを表示することです。

class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(author=request.user)
ModelAdmin.message_user(request, message, level=messages.INFO, extra_tags=, fail_silently=False)

django.contrib.messages バックエンドを使用してユーザーにメッセージを送信します。 カスタムModelAdminの例を参照してください。

キーワード引数を使用すると、メッセージレベルを変更したり、CSSタグを追加したり、contrib.messagesフレームワークがインストールされていない場合にサイレントに失敗したりできます。 これらのキーワード引数は、 django.contrib.messages.add_message()の引数と一致します。詳細については、その関数のドキュメントを参照してください。 1つの違いは、レベルが整数/定数に加えて文字列ラベルとして渡される可能性があることです。

ModelAdmin.get_paginator(request, queryset, per_page, orphans=0, allow_empty_first_page=True)
このビューに使用するページネーターのインスタンスを返します。 デフォルトでは、 paginator のインスタンスをインスタンス化します。
ModelAdmin.response_add(request, obj, post_url_continue=None)

add_view()ステージの HttpResponse を決定します。

response_addは、管理フォームが送信された後、オブジェクトと関連するすべてのインスタンスが作成および保存された直後に呼び出されます。 オブジェクトが作成された後、これをオーバーライドしてデフォルトの動作を変更できます。

ModelAdmin.response_change(request, obj)

change_view()ステージの HttpResponse を決定します。

response_changeは、管理フォームが送信された後、オブジェクトと関連するすべてのインスタンスが保存された直後に呼び出されます。 オブジェクトが変更された後、それをオーバーライドしてデフォルトの動作を変更できます。

ModelAdmin.response_delete(request, obj_display, obj_id)

delete_view()ステージの HttpResponse を決定します。

response_deleteは、オブジェクトが削除された後に呼び出されます。 オブジェクトが削除された後、これをオーバーライドしてデフォルトの動作を変更できます。

obj_displayは、削除されたオブジェクトの名前が付いた文字列です。

obj_idは、削除するオブジェクトを取得するために使用されるシリアル化された識別子です。

ModelAdmin.get_changeform_initial_data(request)

管理者変更フォームの初期データのフック。 デフォルトでは、フィールドにはGETパラメーターから初期値が与えられます。 たとえば、?name=initial_valueは、nameフィールドの初期値をinitial_valueに設定します。

このメソッドは、{'fieldname': 'fieldval'}の形式で辞書を返す必要があります。

def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}
ModelAdmin.get_deleted_objects(objs, request)

delete_view()の削除プロセスと「選択した削除」アクションをカスタマイズするためのフック。

objs引数は、削除されるオブジェクト(QuerySetまたはモデルインスタンスのリスト)の同種の反復可能であり、requestHttpRequest です。

このメソッドは、(deleted_objects, model_count, perms_needed, protected)の4タプルを返す必要があります。

deleted_objectsは、削除されるすべてのオブジェクトを表す文字列のリストです。 削除する関連オブジェクトがある場合、リストはネストされ、それらの関連オブジェクトが含まれます。 リストは、:tfilter: `unordered_list` フィルターを使用してテンプレートでフォーマットされます。

model_countは、各モデルの verbose_name_plural を削除されるオブジェクトの数にマッピングする辞書です。

perms_neededは、ユーザーが削除する権限を持たないモデルの verbose_name のセットです。

protectedは、削除できないすべての保護された関連オブジェクトを表す文字列のリストです。 リストがテンプレートに表示されます。

他の方法

ModelAdmin.add_view(request, form_url=, extra_context=None)
モデルインスタンス追加ページのDjangoビュー。 以下の注を参照してください。
ModelAdmin.change_view(request, object_id, form_url=, extra_context=None)
モデルインスタンス編集ページのDjangoビュー。 以下の注を参照してください。
ModelAdmin.changelist_view(request, extra_context=None)
モデルインスタンスの変更リスト/アクションページのDjangoビュー。 以下の注を参照してください。
ModelAdmin.delete_view(request, object_id, extra_context=None)
モデルインスタンスの削除確認ページのDjangoビュー。 以下の注を参照してください。
ModelAdmin.history_view(request, object_id, extra_context=None)
特定のモデルインスタンスの変更履歴を表示するページのDjangoビュー。

前のセクションで説明したフックタイプのModelAdminメソッドとは異なり、これらの5つのメソッドは、実際には、管理アプリケーションのURLディスパッチングハンドラーからDjangoビューとして呼び出され、モデルインスタンスのCRUD操作を処理するページをレンダリングするように設計されています。 その結果、これらのメソッドを完全にオーバーライドすると、管理アプリケーションの動作が大幅に変更されます。

これらのメソッドをオーバーライドする一般的な理由の1つは、ビューをレンダリングするテンプレートに提供されるコンテキストデータを拡張することです。 次の例では、変更ビューがオーバーライドされ、レンダリングされたテンプレートに、他の方法では利用できない追加のマッピングデータが提供されます。

class MyModelAdmin(admin.ModelAdmin):

    # A template for a very customized change view:
    change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'

    def get_osm_info(self):
        # ...
        pass

    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['osm_data'] = self.get_osm_info()
        return super().change_view(
            request, object_id, form_url, extra_context=extra_context,
        )

これらのビューは TemplateResponse インスタンスを返し、レンダリング前に応答データを簡単にカスタマイズできます。 詳細については、 TemplateResponseのドキュメントを参照してください。


ModelAdminアセットの定義

追加/変更ビューにCSSやJavaScriptを少し追加したい場合があります。 これは、ModelAdminMedia内部クラスを使用することで実現できます。

class ArticleAdmin(admin.ModelAdmin):
    class Media:
        css = {
            "all": ("my_styles.css",)
        }
        js = ("my_code.js",)

staticfiles app:setting: `STATIC_URL` (または:setting:` MEDIA_URL` if :setting: `STATIC_URL` is None)任意のアセットパスへ。 フォームの通常のアセット定義と同じルールが適用されます。

jQuery

Django admin JavaScriptは、 jQuery ライブラリを利用します。

ユーザー提供のスクリプトまたはライブラリとの競合を回避するために、DjangoのjQuery(バージョン3.5.1)はdjango.jQueryという名前空間になっています。 2番目のコピーを含めずに独自の管理JavaScriptでjQueryを使用する場合は、チェンジリストのdjango.jQueryオブジェクトを使用して、ビューを追加/編集できます。 また、フォームメディアアセットを宣言するときは、django.jQueryに応じて独自の管理フォームまたはウィジェットでjs=['admin/js/jquery.init.js', …]を指定する必要があります。

バージョン3.1で変更: jQueryが3.4.1から3.5.1にアップグレードされました。


ModelAdmin クラスはデフォルトでjQueryを必要とするため、特別な必要がない限り、ModelAdminのメディアリソースのリストにjQueryを追加する必要はありません。 たとえば、jQueryライブラリをグローバル名前空間に含める必要がある場合(たとえば、サードパーティのjQueryプラグインを使用する場合)、または新しいバージョンのjQueryが必要な場合は、独自のコピーを含める必要があります。

Djangoは、非圧縮バージョンと「縮小」バージョンの両方を、それぞれjquery.jsおよびjquery.min.jsとして提供します。

ModelAdmin および InlineModelAdmin にはmediaプロパティがあり、フォームやフォームセットのJavaScriptファイルへのパスを格納するMediaオブジェクトのリストを返します。 。 :setting: `DEBUG`Trueの場合、jquery.jsを含むさまざまなJavaScriptファイルの非圧縮バージョンが返されます。 そうでない場合は、「縮小」バージョンが返されます。


管理者にカスタム検証を追加する

管理者にデータのカスタム検証を追加することもできます。 自動管理インターフェースは django.forms を再利用し、ModelAdminクラスは独自のフォームを定義する機能を提供します。

class ArticleAdmin(admin.ModelAdmin):
    form = MyArticleAdminForm

MyArticleAdminFormは、必要な場所にインポートする限り、どこでも定義できます。 これで、フォーム内で、任意のフィールドに独自のカスタム検証を追加できます。

class MyArticleAdminForm(forms.ModelForm):
    def clean_name(self):
        # do something that validates your data
        return self.cleaned_data["name"]

ここでModelFormを使用することが重要です。そうしないと、問題が発生する可能性があります。 詳細については、カスタム検証に関するフォームのドキュメント、より具体的には、モデルフォーム検証ノートを参照してください。


InlineModelAdminオブジェクト

class InlineModelAdmin
class TabularInline
class StackedInline

管理インターフェースには、親モデルと同じページでモデルを編集する機能があります。 これらはインラインと呼ばれます。 次の2つのモデルがあるとします。

from django.db import models

class Author(models.Model):
   name = models.CharField(max_length=100)

class Book(models.Model):
   author = models.ForeignKey(Author, on_delete=models.CASCADE)
   title = models.CharField(max_length=100)

著者ページで、著者が執筆した本を編集できます。 ModelAdmin.inlinesでインラインを指定して、モデルにインラインを追加します。

from django.contrib import admin

class BookInline(admin.TabularInline):
    model = Book

class AuthorAdmin(admin.ModelAdmin):
    inlines = [
        BookInline,
    ]

DjangoはInlineModelAdminの2つのサブクラスを提供します。それらは次のとおりです。

これら2つの違いは、それらをレンダリングするために使用されるテンプレートにすぎません。

InlineModelAdminオプション

InlineModelAdminは、ModelAdminと同じ機能の多くを共有し、独自の機能をいくつか追加します(共有機能は、実際にはBaseModelAdminスーパークラスで定義されています)。 共有機能は次のとおりです。

InlineModelAdminクラスは、以下を追加またはカスタマイズします。

InlineModelAdmin.model
インラインで使用しているモデル。 これは必須です。
InlineModelAdmin.fk_name
モデルの外部キーの名前。 ほとんどの場合、これは自動的に処理されますが、同じ親モデルに複数の外部キーがある場合は、fk_nameを明示的に指定する必要があります。
InlineModelAdmin.formset
これはデフォルトで BaseInlineFormSet になります。 独自のフォームセットを使用すると、カスタマイズの多くの可能性が得られます。 インラインは、モデルフォームセットを中心に構築されています。
InlineModelAdmin.form
formの値はデフォルトでModelFormになります。 これは、このインラインのフォームセットを作成するときに inlineformset_factory()に渡されるものです。

警告

InlineModelAdminフォームのカスタム検証を作成するときは、親モデルの機能に依存する検証を作成する場合は注意が必要です。 親モデルが検証に失敗した場合、 ModelFormでの検証の警告で説明されているように、一貫性のない状態のままになる可能性があります。


InlineModelAdmin.classes
インライン用にレンダリングされるフィールドセットに適用する追加のCSSクラスを含むリストまたはタプル。 デフォルトはNoneです。 fieldsets で構成されたクラスと同様に、collapseクラスのインラインは最初に折りたたまれ、ヘッダーには小さな「show」リンクがあります。
InlineModelAdmin.extra

これは、初期フォームに加えてフォームセットが表示する追加のフォームの数を制御します。 デフォルトは3です。 詳細については、フォームセットのドキュメントを参照してください。

JavaScript対応のブラウザーを使用しているユーザーには、extra引数の結果として提供されるインラインに加えて、任意の数のインラインを追加できるようにする「別の追加」リンクが提供されます。

現在表示されているフォームの数がmax_numを超えている場合、またはユーザーがJavaScriptを有効にしていない場合、ダイナミックリンクは表示されません。

InlineModelAdmin.get_extra()では、追加のフォームの数をカスタマイズすることもできます。

InlineModelAdmin.max_num

これは、インラインで表示するフォームの最大数を制御します。 これはオブジェクトの数とは直接相関しませんが、値が十分に小さい場合は相関します。 詳細については、編集可能なオブジェクトの数を制限するを参照してください。

InlineModelAdmin.get_max_num()では、追加フォームの最大数をカスタマイズすることもできます。

InlineModelAdmin.min_num

これは、インラインで表示するフォームの最小数を制御します。 詳細については、 modelformset_factory()を参照してください。

InlineModelAdmin.get_min_num()では、表示されるフォームの最小数をカスタマイズすることもできます。

InlineModelAdmin.raw_id_fields

デフォルトでは、Djangoの管理者は選択ボックスインターフェースを使用します( )であるフィールドの場合ForeignKey。 ドロップダウンに表示する関連するすべてのインスタンスを選択する必要があるというオーバーヘッドを発生させたくない場合があります。

raw_id_fieldsは、ForeignKeyまたはManyToManyFieldのいずれかのInputウィジェットに変更するフィールドのリストです。

class BookInline(admin.TabularInline):
    model = Book
    raw_id_fields = ("pages",)
InlineModelAdmin.template
ページにインラインをレンダリングするために使用されるテンプレート。
InlineModelAdmin.verbose_name
モデルの内部Metaクラスにあるverbose_nameのオーバーライド。
InlineModelAdmin.verbose_name_plural
モデルの内部Metaクラスにあるverbose_name_pluralのオーバーライド。
InlineModelAdmin.can_delete
インラインオブジェクトをインラインで削除できるかどうかを指定します。 デフォルトはTrueです。
InlineModelAdmin.show_change_link
管理者で変更できるインラインオブジェクトに変更フォームへのリンクがあるかどうかを指定します。 デフォルトはFalseです。
InlineModelAdmin.get_formset(request, obj=None, **kwargs)
管理者の追加/変更ビューで使用する BaseInlineFormSet クラスを返します。 objは編集中の親オブジェクトであり、新しい親を追加する場合はNoneです。 ModelAdmin.get_formsets_with_inlines の例を参照してください。
InlineModelAdmin.get_extra(request, obj=None, **kwargs)

使用する追加のインラインフォームの数を返します。 デフォルトでは、 InlineModelAdmin.extra 属性を返します。

このメソッドをオーバーライドして、追加のインラインフォームの数をプログラムで決定します。 たとえば、これはモデルインスタンスに基づいている場合があります(キーワード引数objとして渡されます)。

class BinaryTreeAdmin(admin.TabularInline):
    model = BinaryTree

    def get_extra(self, request, obj=None, **kwargs):
        extra = 2
        if obj:
            return extra - obj.binarytree_set.count()
        return extra
InlineModelAdmin.get_max_num(request, obj=None, **kwargs)

使用する追加のインラインフォームの最大数を返します。 デフォルトでは、 InlineModelAdmin.max_num 属性を返します。

このメソッドをオーバーライドして、インラインフォームの最大数をプログラムで決定します。 たとえば、これはモデルインスタンスに基づいている場合があります(キーワード引数objとして渡されます)。

class BinaryTreeAdmin(admin.TabularInline):
    model = BinaryTree

    def get_max_num(self, request, obj=None, **kwargs):
        max_num = 10
        if obj and obj.parent:
            return max_num - 5
        return max_num
InlineModelAdmin.get_min_num(request, obj=None, **kwargs)

使用するインラインフォームの最小数を返します。 デフォルトでは、 InlineModelAdmin.min_num 属性を返します。

このメソッドをオーバーライドして、インラインフォームの最小数をプログラムで決定します。 たとえば、これはモデルインスタンスに基づいている場合があります(キーワード引数objとして渡されます)。

InlineModelAdmin.has_add_permission(request, obj)
インラインオブジェクトの追加が許可されている場合はTrueを返し、許可されていない場合はFalseを返す必要があります。 objは編集中の親オブジェクトであり、新しい親を追加する場合はNoneです。
InlineModelAdmin.has_change_permission(request, obj=None)
インラインオブジェクトの編集が許可されている場合はTrueを返し、許可されていない場合はFalseを返す必要があります。 objは、編集中の親オブジェクトです。
InlineModelAdmin.has_delete_permission(request, obj=None)
インラインオブジェクトの削除が許可されている場合はTrueを返し、許可されていない場合はFalseを返す必要があります。 objは、編集中の親オブジェクトです。

ノート

InlineModelAdminメソッドに渡されるobj引数は、編集中の親オブジェクト、または新しい親を追加するときのNoneです。


同じ親モデルへの2つ以上の外部キーを持つモデルの操作

同じモデルに対して複数の外部キーを持つことが可能な場合があります。 このモデルを例にとってみましょう。

from django.db import models

class Friendship(models.Model):
    to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends")
    from_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="from_friends")

Person管理者の追加/変更ページにインラインを表示する場合は、外部キーを自動的に定義できないため、明示的に定義する必要があります。

from django.contrib import admin
from myapp.models import Friendship

class FriendshipInline(admin.TabularInline):
    model = Friendship
    fk_name = "to_person"

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        FriendshipInline,
    ]

多対多モデルの操作

デフォルトでは、多対多関係の管理ウィジェットは、 ManyToManyField への実際の参照が含まれているモデルに表示されます。 ModelAdminの定義に応じて、モデルの多対多の各フィールドは、標準のHTML <select multiple>、水平または垂直フィルター、またはraw_id_fieldsウィジェットで表されます。 。 ただし、これらのウィジェットをインラインに置き換えることもできます。

次のモデルがあるとします。

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, related_name='groups')

インラインを使用して多対多の関係を表示する場合は、関係のInlineModelAdminオブジェクトを定義することで実行できます。

from django.contrib import admin

class MembershipInline(admin.TabularInline):
    model = Group.members.through

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]
    exclude = ('members',)

この例で注目に値する2つの機能があります。

まず、MembershipInlineクラスはGroup.members.throughを参照します。 through属性は、多対多の関係を管理するモデルへの参照です。 このモデルは、多対多のフィールドを定義すると、Djangoによって自動的に作成されます。

次に、GroupAdminmembersフィールドを手動で除外する必要があります。 Djangoは、関係(この場合はGroup)を定義するモデルの多対多フィールドの管理ウィジェットを表示します。 多対多の関係を表すためにインラインモデルを使用する場合は、Djangoの管理者にこのウィジェットを表示しない表示しないように指示する必要があります。そうしないと、管理ページに2つのウィジェットが表示されます。関係。

この手法を使用する場合、 m2m_changed 信号はトリガーされないことに注意してください。 これは、管理者に関する限り、throughは多対多の関係ではなく、2つの外部キーフィールドを持つ単なるモデルであるためです。

他のすべての点で、InlineModelAdminは他のものとまったく同じです。 通常のModelAdminプロパティのいずれかを使用して、外観をカスタマイズできます。


多対多の中間モデルでの作業

through引数を使用して ManyToManyField に中間モデルを指定すると、管理者はデフォルトでウィジェットを表示しません。 これは、その中間モデルの各インスタンスが単一のウィジェットに表示できるよりも多くの情報を必要とし、複数のウィジェットに必要なレイアウトが中間モデルによって異なるためです。

ただし、その情報をインラインで編集できるようにしたいのです。 幸い、これはインライン管理モデルで実行できます。 次のモデルがあるとします。

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

管理者にこの中間モデルを表示する最初のステップは、Membershipモデルのインラインクラスを定義することです。

class MembershipInline(admin.TabularInline):
    model = Membership
    extra = 1

この例では、MembershipモデルのデフォルトのInlineModelAdmin値を使用し、追加の追加フォームを1つに制限しています。 これは、InlineModelAdminクラスで使用可能なオプションのいずれかを使用してカスタマイズできます。

次に、PersonおよびGroupモデルの管理ビューを作成します。

class PersonAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class GroupAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

最後に、PersonおよびGroupモデルを管理サイトに登録します。

admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)

これで、管理サイトは、PersonまたはGroupの詳細ページからMembershipオブジェクトをインラインで編集するように設定されました。


ジェネリックリレーションをインラインとして使用する

一般的に関連するオブジェクトでインラインを使用することが可能です。 次のモデルがあるとします。

from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import models

class Image(models.Model):
    image = models.ImageField(upload_to="images")
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

class Product(models.Model):
    name = models.CharField(max_length=100)

ProductImageインスタンスの編集と作成を許可する場合は、 GenericTabularInline または GenericStackedInline (両方のサブクラス)を使用してビューを追加/変更できます。 admin によって提供される GenericInlineModelAdmin )の。 それらは、非ジェネリックの対応物と同じように、インラインオブジェクトを表すフォームの表形式およびスタック形式のビジュアルレイアウトをそれぞれ実装します。 それらは他のインラインと同じように動作します。 このサンプルアプリのadmin.pyでは、次のようになります。

from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline

from myapp.models import Image, Product

class ImageInline(GenericTabularInline):
    model = Image

class ProductAdmin(admin.ModelAdmin):
    inlines = [
        ImageInline,
    ]

admin.site.register(Product, ProductAdmin)

より具体的な情報については、 contenttypesのドキュメントを参照してください。


管理テンプレートのオーバーライド

管理モジュールが管理サイトのさまざまなページを生成するために使用するテンプレートの多くをオーバーライドできます。 特定のアプリまたは特定のモデルに対して、これらのテンプレートのいくつかをオーバーライドすることもできます。

プロジェクト管理テンプレートディレクトリを設定します

管理用テンプレートファイルは、contrib/admin/templates/adminディレクトリにあります。

それらの1つ以上をオーバーライドするには、最初にプロジェクトのtemplatesディレクトリにadminディレクトリを作成します。 これは、で指定した任意のディレクトリにすることができます。 :setting: `DIRS ` のオプションDjangoTemplatesのバックエンド :setting: `TEMPLATES` 設定。 'loaders'オプションをカスタマイズした場合は、'django.template.loaders.filesystem.Loader''django.template.loaders.app_directories.Loader'の前に表示されるようにして、カスタムテンプレートが[X199Xに含まれているものよりも前にテンプレート読み込みシステムによって検出されるようにします。 ] django.contrib.admin 。

このadminディレクトリ内に、アプリにちなんで名付けられたサブディレクトリを作成します。 これらのアプリサブディレクトリ内に、モデルにちなんで名付けられたサブディレクトリを作成します。 管理アプリはディレクトリを探すときにモデル名を小文字にすることに注意してください。大文字と小文字を区別するファイルシステムでアプリを実行する場合は、ディレクトリにすべて小文字で名前を付けるようにしてください。

特定のアプリの管理用テンプレートを上書きするには、django/contrib/admin/templates/adminディレクトリからテンプレートをコピーして編集し、作成したディレクトリの1つに保存します。

たとえば、my_appという名前のアプリのすべてのモデルの変更リストビューにツールを追加する場合は、contrib/admin/templates/admin/change_list.htmltemplates/admin/my_app/ディレクトリにコピーします。プロジェクトを作成し、必要な変更を加えます。

'Page'という名前の特定のモデルのみの変更リストビューにツールを追加する場合は、同じファイルをプロジェクトのtemplates/admin/my_app/pageディレクトリにコピーします。


オーバーライドvs。 管理者テンプレートの置き換え

管理用テンプレートはモジュール式に設計されているため、通常、テンプレート全体を置き換える必要はなく、お勧めできません。 ほとんどの場合、変更する必要のあるテンプレートのセクションのみをオーバーライドすることをお勧めします。

上記の例を続けるために、PageモデルのHistoryツールの横に新しいリンクを追加します。 change_form.htmlを確認した後、object-tools-itemsブロックをオーバーライドするだけでよいことがわかりました。 したがって、ここに新しいchange_form.htmlがあります:

{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
    <li>
        <a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% translate "History" %}</a>
    </li>
    <li>
        <a href="mylink/" class="historylink">My Link</a>
    </li>
    {% if has_absolute_url %}
        <li>
            <a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% translate "View on site" %}</a>
        </li>
    {% endif %}
{% endblock %}

以上です! このファイルをtemplates/admin/my_appディレクトリに配置すると、my_app内のすべてのモデルの変更フォームにリンクが表示されます。


アプリまたはモデルごとに上書きされる可能性のあるテンプレート

contrib/admin/templates/adminのすべてのテンプレートがアプリごとまたはモデルごとに上書きされるわけではありません。 次のことができます:

  • actions.html
  • app_index.html
  • change_form.html
  • change_form_object_tools.html
  • change_list.html
  • change_list_object_tools.html
  • change_list_results.html
  • date_hierarchy.html
  • delete_confirmation.html
  • object_history.html
  • pagination.html
  • popup_response.html
  • prepopulated_fields_js.html
  • search_form.html
  • submit_line.html

この方法でオーバーライドできないテンプレートの場合でも、templates/adminディレクトリに新しいバージョンを配置することで、プロジェクト全体でテンプレートをオーバーライドできます。 これは、カスタム404ページと500ページを作成する場合に特に便利です。

ノート

change_list_results.htmlなどの一部の管理テンプレートは、カスタム包含タグをレンダリングするために使用されます。 これらは上書きされる可能性がありますが、そのような場合は、問題のタグの独自のバージョンを作成し、それに別の名前を付ける方がよいでしょう。 そうすれば、それを選択的に使用できます。


ルートおよびログインテンプレート

インデックス、ログイン、またはログアウトのテンプレートを変更する場合は、独自のAdminSiteインスタンスを作成し(以下を参照)、 AdminSite.index_templateAdminSiteを変更することをお勧めします。 login_template または AdminSite.logout_template プロパティ。


テーマのサポート

バージョン3.2の新機能。


管理者はCSS変数を使用して色を定義します。 これにより、多くの個別のCSSルールを上書きすることなく色を変更できます。 たとえば、青ではなく紫を使用したい場合は、プロジェクトにadmin/base.htmlテンプレートオーバーライドを追加できます。

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

{% block extrahead %}{{ block.super }}
<style>
:root {
  --primary: #9774d5;
  --secondary: #785cab;
  --link-fg: #7c449b;
  --link-selected-fg: #8f5bb2;
}
</style>
{% endblock %}

ダークテーマが定義され、 refers-color-scheme メディアクエリを尊重して適用されます。

CSS変数のリストはdjango/contrib/admin/static/admin/css/base.cssで定義されています。


AdminSiteオブジェクト

class AdminSite(name='admin')

Django管理サイトは、django.contrib.admin.sites.AdminSiteのインスタンスで表されます。 デフォルトでは、このクラスのインスタンスはdjango.contrib.admin.siteとして作成され、モデルとModelAdminインスタンスを登録できます。

デフォルトの管理サイトをカスタマイズする場合は、オーバーライドできます。

AdminSiteのインスタンスを作成する場合、コンストラクターにname引数を使用して一意のインスタンス名を指定できます。 このインスタンス名は、特に管理URLを逆にするの場合に、インスタンスを識別するために使用されます。 インスタンス名が指定されていない場合、デフォルトのインスタンス名adminが使用されます。 AdminSite クラスをカスタマイズする例については、 AdminSiteクラスのカスタマイズを参照してください。

AdminSite属性

テンプレートは、管理テンプレートのオーバーライドで説明されているように、基本管理テンプレートをオーバーライドまたは拡張できます。

AdminSite.site_header
<h1>(文字列)として、各管理ページの上部に配置するテキスト。 デフォルトでは、これは「Django管理」です。
AdminSite.site_title
各管理ページの<title>(文字列)の最後に配置するテキスト。 デフォルトでは、これは「Djangoサイト管理者」です。
AdminSite.site_url

各管理ページの上部にある「サイトの表示」リンクのURL。 デフォルトでは、site_url/です。 リンクを削除するには、Noneに設定します。

サブパスで実行されているサイトの場合、 each_context()メソッドは、現在のリクエストにrequest.META['SCRIPT_NAME']が設定されているかどうかを確認し、site_urlが以外に設定されていない場合はその値を使用します/

AdminSite.index_title
管理者インデックスページの上部に配置するテキスト(文字列)。 デフォルトでは、これは「サイト管理」です。
AdminSite.index_template
管理サイトのメインインデックスビューで使用されるカスタムテンプレートへのパス。
AdminSite.app_index_template
管理サイトアプリのインデックスビューで使用されるカスタムテンプレートへのパス。
AdminSite.empty_value_display
管理サイトの変更リストに空の値を表示するために使用する文字列。 デフォルトはダッシュです。 フィールドにempty_value_display属性を設定することにより、ModelAdminごと、およびModelAdmin内のカスタムフィールドで値をオーバーライドすることもできます。 例については、 ModelAdmin.empty_value_display を参照してください。
AdminSite.enable_nav_sidebar

バージョン3.1の新機能。

大画面にナビゲーションサイドバーを表示するかどうかを決定するブール値。 デフォルトでは、Trueに設定されています。

AdminSite.final_catch_all_view

バージョン3.2の新機能。

認証されていないユーザーをログインページにリダイレクトする最終的なキャッチオールビューを管理者に追加するかどうかを決定するブール値。 デフォルトでは、Trueに設定されています。

警告

これをFalseに設定することは、ビューが潜在的なモデル列挙のプライバシーの問題から保護するため、お勧めしません。

AdminSite.login_template
管理サイトのログインビューで使用されるカスタムテンプレートへのパス。
AdminSite.login_form
管理サイトのログインビューで使用される AuthenticationForm のサブクラス。
AdminSite.logout_template
管理サイトのログアウトビューで使用されるカスタムテンプレートへのパス。
AdminSite.password_change_template
管理サイトのパスワード変更ビューで使用されるカスタムテンプレートへのパス。
AdminSite.password_change_done_template
管理サイトのパスワード変更完了ビューで使用されるカスタムテンプレートへのパス。


AdminSiteメソッド

AdminSite.each_context(request)

管理サイトのすべてのページのテンプレートコンテキストに配置する変数の辞書を返します。

デフォルトでは、次の変数と値が含まれています。

  • site_headerAdminSite.site_header

  • site_titleAdminSite.site_title

  • site_urlAdminSite.site_url

  • has_permissionAdminSite.has_permission()

  • available_apps:現在のユーザーが利用できるアプリケーションレジストリのアプリケーションのリスト。 リストの各エントリは、次のキーを持つアプリケーションを表すdictです。

    • app_label:アプリケーションラベル

    • app_url:管理者のアプリケーションインデックスのURL

    • has_module_perms:モジュールのインデックスページの表示とアクセスが現在のユーザーに許可されているかどうかを示すブール値

    • models:アプリケーションで利用可能なモデルのリスト

    各モデルは、次のキーを持つdictです。

    • object_name:モデルのクラス名

    • name:モデルの複数形の名前

    • permsdict追跡addchangedelete、およびview権限

    • admin_url:モデルの管理者変更リストURL

    • add_url:新しいモデルインスタンスを追加するための管理URL

AdminSite.has_permission(request)
指定されたHttpRequestのユーザーが、管理サイトの少なくとも1つのページを表示する権限を持っている場合、Trueを返します。 デフォルトでは、 User.is_activeUser.is_staff の両方がTrueである必要があります。
AdminSite.register(model_or_iterable, admin_class=None, **options)

指定されたモデルクラス(またはクラスの反復可能)を指定されたadmin_classに登録します。 admin_classのデフォルトは ModelAdmin (デフォルトの管理オプション)です。 キーワード引数が指定されている場合-例: list_display –これらはadminクラスのオプションとして適用されます。

モデルが抽象である場合、 ImpproperlyConfigured を発生させます。 モデルがすでに登録されている場合は、django.contrib.admin.sites.AlreadyRegistered

AdminSite.unregister(model_or_iterable)

指定されたモデルクラス(またはクラスの反復可能)の登録を解除します。

モデルがまだ登録されていない場合は、django.contrib.admin.sites.NotRegisteredを発生させます。


AdminSiteインスタンスをURLconfにフックする

Django管理者を設定する最後のステップは、AdminSiteインスタンスをURLconfにフックすることです。 これを行うには、特定のURLをAdminSite.urlsメソッドにポイントします。 include()を使用する必要はありません。

この例では、デフォルトのAdminSiteインスタンスdjango.contrib.admin.siteをURL /admin/に登録します。

# urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

AdminSite クラスのカスタマイズ

カスタム動作を使用して独自の管理サイトを設定する場合は、AdminSiteをサブクラス化して、好きなものをオーバーライドまたは追加できます。 次に、AdminSiteサブクラスのインスタンスを作成し(他のPythonクラスをインスタンス化するのと同じ方法で)、モデルとModelAdminサブクラスをデフォルトサイトではなくそのインスタンスに登録します。 最後に、myproject/urls.pyを更新して、 AdminSite サブクラスを参照します。

myapp / admin.py

from django.contrib.admin import AdminSite

from .models import MyModel

class MyAdminSite(AdminSite):
    site_header = 'Monty Python administration'

admin_site = MyAdminSite(name='myadmin')
admin_site.register(MyModel)

myproject / urls.py

from django.urls import path

from myapp.admin import admin_site

urlpatterns = [
    path('myadmin/', admin_site.urls),
]

独自のAdminSiteインスタンスを使用する場合は、 [にアプリごとのadminモジュールをすべてインポートする可能性があるため、adminモジュールの自動検出が不要な場合があることに注意してください。 X182X]モジュール。 つまり、:setting: `INSTALLED_APPS` 設定で、'django.contrib.admin'の代わりに'django.contrib.admin.apps.SimpleAdminConfig'を配置する必要があります。


デフォルトの管理サイトを上書きする

カスタムAppConfigdefault_site 属性を、AdminSiteサブクラスまたは呼び出し可能オブジェクトのドット付きインポートパスに設定することで、デフォルトのdjango.contrib.admin.siteをオーバーライドできます。サイトインスタンスを返します。

myproject / admin.py

from django.contrib import admin

class MyAdminSite(admin.AdminSite):
    ...

myproject / apps.py

from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'myproject.admin.MyAdminSite'

myproject / settings.py

INSTALLED_APPS = [
    ...
    'myproject.apps.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...
]

同じURLconf内の複数の管理サイト

同じDjangoを利用したWebサイトに管理サイトの複数のインスタンスを作成できます。 AdminSiteの複数のインスタンスを作成し、それぞれを異なるURLに配置します。

この例では、URL /basic-admin//advanced-admin/は、AdminSiteインスタンスmyproject.admin.basic_sitemyproject.admin.advanced_siteを使用して、管理サイトの個別のバージョンを備えています。それぞれ:

# urls.py
from django.urls import path
from myproject.admin import advanced_site, basic_site

urlpatterns = [
    path('basic-admin/', basic_site.urls),
    path('advanced-admin/', advanced_site.urls),
]

AdminSiteインスタンスは、コンストラクターへの単一の引数、名前を取ります。これは、好きなものにすることができます。 この引数は、それらを逆にするためにURL名のプレフィックスになります。 これは、複数のAdminSiteを使用している場合にのみ必要です。


管理サイトへのビューの追加

ModelAdmin と同様に、 AdminSite は、サイトの追加ビューを定義するためにオーバーライドできる get_urls()メソッドを提供します。 管理サイトに新しいビューを追加するには、ベースの get_urls()メソッドを拡張して、新しいビューのパターンを含めます。

ノート

管理テンプレートを使用する、または基本管理テンプレートを拡張するレンダリングするビューは、テンプレートをレンダリングする前にrequest.current_appを設定する必要があります。 ビューがAdminSite上にある場合はself.nameに設定するか、ビューがModelAdmin上にある場合はself.admin_site.nameに設定する必要があります。


パスワードリセット機能の追加

URLconfに数行追加することで、管理サイトにパスワードリセット機能を追加できます。 具体的には、次の4つのパターンを追加します。

from django.contrib.auth import views as auth_views

path(
    'admin/password_reset/',
    auth_views.PasswordResetView.as_view(),
    name='admin_password_reset',
),
path(
    'admin/password_reset/done/',
    auth_views.PasswordResetDoneView.as_view(),
    name='password_reset_done',
),
path(
    'reset/<uidb64>/<token>/',
    auth_views.PasswordResetConfirmView.as_view(),
    name='password_reset_confirm',
),
path(
    'reset/done/',
    auth_views.PasswordResetCompleteView.as_view(),
    name='password_reset_complete',
),

(これは、admin/に管理者を追加したことを前提としており、管理者アプリ自体を含む行の前に^admin/で始まるURLを配置する必要があります)。

admin_password_resetという名前のURLが存在すると、「パスワードを忘れましたか?」 パスワードボックスの下のデフォルトの管理者ログインページに表示されるリンク。


LogEntryオブジェクト

class models.LogEntry
LogEntryクラスは、管理インターフェイスを介して行われたオブジェクトの追加、変更、および削除を追跡します。

LogEntry属性

LogEntry.action_time
アクションの日時。
LogEntry.user
アクションを実行したユーザー(:setting: `AUTH_USER_MODEL` インスタンス)。
LogEntry.content_type
変更されたオブジェクトの ContentType
LogEntry.object_id
変更されたオブジェクトの主キーのテキスト表現。
LogEntry.object_repr
変更後のオブジェクトのrepr()
LogEntry.action_flag

ログに記録されるアクションのタイプ:ADDITIONCHANGEDELETION

たとえば、管理者を通じて行われたすべての追加のリストを取得するには、次のようにします。

from django.contrib.admin.models import ADDITION, LogEntry

LogEntry.objects.filter(action_flag=ADDITION)
LogEntry.change_message
変更の詳細な説明。 たとえば、編集の場合、メッセージには編集されたフィールドのリストが含まれます。 Django管理サイトはこのコンテンツをJSON構造としてフォーマットし、 get_change_message()が現在のユーザー言語に翻訳されたメッセージを再構成できるようにします。 ただし、カスタムコードでは、これをプレーンな文字列として設定する場合があります。 この値に直接アクセスするのではなく、 get_change_message()メソッドを使用してこの値を取得することをお勧めします。


LogEntryメソッド

LogEntry.get_edited_object()
参照されたオブジェクトを返すショートカット。
LogEntry.get_change_message()
change_message をフォーマットして現在のユーザー言語に変換します。 Django 1.10より前に作成されたメッセージは、常にログに記録された言語で表示されます。


管理URLを逆にする

AdminSite がデプロイされると、そのサイトによって提供されるビューには、Djangoの URL反転システムを使用してアクセスできます。

AdminSite は、次の名前付きURLパターンを提供します。

ページ URL名 パラメーター
索引 index
ログイン login
ログアウト logout
パスワードの変更 password_change
パスワードの変更が完了しました password_change_done
i18n JavaScript jsi18n
アプリケーションインデックスページ app_list app_label
オブジェクトのページにリダイレクトする view_on_site content_type_idobject_id

ModelAdmin インスタンスは、名前付きURLの追加セットを提供します。

ページ URL名 パラメーター
変更リスト テンプレート:App label_テンプレート:Model name_changelist
追加 テンプレート:App label_テンプレート:Model name_add
歴史 テンプレート:App label_テンプレート:Model name_history object_id
消去 テンプレート:App label_テンプレート:Model name_delete object_id
変化する テンプレート:App label_テンプレート:Model name_change object_id

UserAdminは、名前付きURLを提供します。

ページ URL名 パラメーター
パスワードの変更 auth_user_password_change user_id

これらの名前付きURLは、アプリケーション名前空間adminと、サイトインスタンスの名前に対応するインスタンス名前空間に登録されます。

したがって、デフォルトの管理者で(ポーリングアプリケーションから)特定のChoiceオブジェクトの変更ビューへの参照を取得する場合は、次のように呼び出します。

>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))

これにより、管理アプリケーションの最初に登録されたインスタンス(インスタンス名が何であれ)が検索され、そのインスタンスのpoll.Choiceインスタンスを変更するためのビューに解決されます。

特定の管理インスタンスでURLを検索する場合は、そのインスタンスの名前をcurrent_appヒントとして逆呼び出しに指定します。 たとえば、customという名前の管理インスタンスからの管理ビューが特に必要な場合は、次のコマンドを呼び出す必要があります。

>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')

詳細については、名前空間URLの反転に関するドキュメントを参照してください。

テンプレート内の管理URLを簡単に元に戻すことができるように、Djangoは引数としてアクションを実行するadmin_urlnameフィルターを提供します。

{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>

上記の例のアクションは、上記の ModelAdmin インスタンスのURL名の最後の部分と一致します。 opts変数は、app_labelおよびmodel_name属性を持つ任意のオブジェクトであり、通常、現在のモデルの管理ビューによって提供されます。


displayデコレータ

display(*, boolean=None, ordering=None, description=None, empty_value=None)

バージョン3.2の新機能。

このデコレータは、 list_display または readonly_fields で使用できるカスタム表示関数に特定の属性を設定するために使用できます。

@admin.display(
    boolean=True,
    ordering='-publish_date',
    description='Is Published?',
)
def is_published(self, obj):
    return obj.publish_date is not None

これは、関数にいくつかの属性(元の長い名前を使用)を直接設定することと同じです。

def is_published(self, obj):
    return obj.publish_date is not None
is_published.boolean = True
is_published.admin_order_field = '-publish_date'
is_published.short_description = 'Is Published?'

また、empty_valueデコレータパラメータは、関数に直接割り当てられたempty_value_display属性にマップされることに注意してください。 booleanと組み合わせて使用することはできません。これらは相互に排他的です。

このデコレータの使用は、表示関数を作成するために必須ではありませんが、関数の目的を識別するためのソースのマーカーとして引数なしで使用すると便利な場合があります。

@admin.display
def published_year(self, obj):
    return obj.publish_date.year

この場合、関数に属性は追加されません。


staff_member_requiredデコレータ

staff_member_required(redirect_field_name='next', login_url='admin:login')

このデコレータは、承認が必要な管理ビューで使用されます。 この関数で装飾されたビューの動作は次のとおりです。

  • ユーザーがログインしていて、スタッフメンバー(User.is_staff=True)であり、アクティブ(User.is_active=True)である場合は、ビューを通常どおり実行します。

  • それ以外の場合、リクエストはlogin_urlパラメータで指定されたURLにリダイレクトされ、redirect_field_nameで指定されたクエリ文字列変数で最初にリクエストされたパスが使用されます。 例:/admin/login/?next=/admin/polls/question/3/

使用例:

from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def my_view(request):
    ...