Django管理サイト
Djangoの最も強力な部分の1つは、自動管理インターフェースです。 モデルからメタデータを読み取り、信頼できるユーザーがサイトのコンテンツを管理できる、モデル中心の迅速なインターフェイスを提供します。 管理者が推奨する使用法は、組織の内部管理ツールに限定されています。 フロントエンド全体を構築するためのものではありません。
管理者にはカスタマイズ用のフックがたくさんありますが、それらのフックを排他的に使用しようとしないように注意してください。 データベースのテーブルとフィールドの実装の詳細を抽象化する、よりプロセス中心のインターフェイスを提供する必要がある場合は、おそらく独自のビューを作成するときです。
このドキュメントでは、Djangoの管理インターフェースをアクティブ化、使用、およびカスタマイズする方法について説明します。
概要
管理者は、:djadmin: `startproject` で使用されるデフォルトのプロジェクトテンプレートで有効になっています。
デフォルトのプロジェクトテンプレートを使用していない場合の要件は次のとおりです。
'django.contrib.admin'
とその依存関係を追加します- django.contrib.auth 、 django.contrib.contenttypes 、 django.contrib.messages 、および[X143X ] django.contrib.sessions -:setting: `INSTALLED_APPS` 設定に。を構成します DjangoTemplates あなたのバックエンド :setting: `TEMPLATES` 設定
django.template.context_processors.request
、django.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'
オプションに追加されました。:setting: `MIDDLEWARE` 設定をカスタマイズした場合、 django.contrib.auth.middleware.AuthenticationMiddleware および django.contrib.messages.middleware.MessageMiddleware [X190X ]を含める必要があります。
管理者の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モデルには
name
、title
、birth_date
の3つのフィールドしかないため、上記の宣言の結果のフォームにはまったく同じフィールドが含まれます。
- ModelAdmin.fields
fields
オプションを使用して、「追加」ページと「変更」ページのフォームで、使用可能なフィールドのサブセットのみを表示したり、順序を変更したり、行にグループ化したりするなど、簡単なレイアウト変更を行います。 たとえば、 django.contrib.flatpages.models.FlatPage モデルの管理フォームのより単純なバージョンを次のように定義できます。class FlatPageAdmin(admin.ModelAdmin): fields = ('url', 'title', 'content')
上記の例では、フィールド
url
、title
、および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つの便利なクラスは、
collapse
とwide
です。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()メソッドを使用して、まったく新しいフォームを指定するのではなく、デフォルトのフォームをカスタマイズすることもできます。例については、管理者へのカスタム検証の追加のセクションを参照してください。
ノート
ModelForm で
Meta.model
属性を定義する場合は、Meta.fields
属性(またはMeta.exclude
属性)も定義する必要があります。 ただし、管理者には独自のフィールド定義方法があるため、Meta.fields
属性は無視されます。ModelForm
が管理者のみに使用される場合、ModelAdmin
が使用する正しいモデルを提供するため、最も簡単な解決策はMeta.model
属性を省略することです。 または、Meta
クラスのfields = []
を設定して、ModelForm
の検証を満たすこともできます。ノート
ModelForm
とModelAdmin
の両方で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_fields
、radio_fields
、またはautocomplete_fields
にそのフィールドの名前が含まれていないことを確認してください。formfield_overrides
では、raw_id_fields
、radio_fields
、またはautocomplete_fields
が設定されているリレーションフィールドのウィジェットを変更できません。 これは、raw_id_fields
、radio_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はTrue
、False
、または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
、またはTrue
、False
、または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_editable
とlist_display_links
の両方に同じフィールドをリストすることはできません。フィールドをフォームとリンクの両方にすることはできません。
これらのルールのいずれかが破られた場合、検証エラーが発生します。
- ModelAdmin.list_filter
次のスクリーンショットに示すように、
list_filter
を設定して、管理者の変更リストページの右側のサイドバーでフィルターをアクティブにします。[[../File:../../../_images/list_filter|../../../_images/list_filter.png]]
list_filter
は要素のリストまたはタプルである必要があり、各要素は次のいずれかのタイプである必要があります。フィールド名。指定するフィールドは、
BooleanField
、CharField
、DateField
、DateTimeField
、IntegerField
、ForeignKey
または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), )
author
がForeignKey
から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
で並べ替えられます。 行が多く、name
とpk
にインデックスがない場合、これはパフォーマンスが低下する可能性があります。
- 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
は、DateTimeField
、ForeignKey
、OneToOneField
、およびManyToManyField
フィールドを受け入れません。バージョン3.2で変更:古いバージョンでは、生成された値からさまざまな英語のストップワードが削除されます。
- ModelAdmin.preserve_filters
- デフォルトでは、適用されたフィルターは、オブジェクトを作成、編集、または削除した後、リストビューに保持されます。 この属性を
False
に設定すると、フィルターをクリアできます。
- ModelAdmin.radio_fields
デフォルトでは、Djangoの管理者は選択ボックスインターフェースを使用します( )であるフィールドの場合
ForeignKey
または持っているchoices
設定。radio_fields
にフィールドが存在する場合、Djangoは代わりにラジオボタンインターフェイスを使用します。group
がPerson
モデルの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
権限を持っている必要があります。結果の順序付けとページ付けは、関連する
ModelAdmin
の get_ordering()および get_paginator()メソッドによって制御されます。次の例では、
ChoiceAdmin
にForeignKey
から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_as
がTrue
の場合、[保存して別のオブジェクトを追加]は、既存のオブジェクトを更新するのではなく、新しいオブジェクト(新しいIDで)を作成する[新規として保存]ボタンに置き換えられます。デフォルトでは、
save_as
はFalse
に設定されています。
- ModelAdmin.save_as_continue
save_as = True の場合、新しいオブジェクトを保存した後のデフォルトのリダイレクトは、そのオブジェクトの変更ビューになります。
save_as_continue=False
を設定すると、リダイレクトはチェンジリストビューになります。デフォルトでは、
save_as_continue
はTrue
に設定されています。
- ModelAdmin.save_on_top
save_on_top
を設定して、管理者変更フォームの上部に保存ボタンを追加します。通常、保存ボタンはフォームの下部にのみ表示されます。
save_on_top
を設定すると、ボタンが上部と下部の両方に表示されます。デフォルトでは、
save_on_top
はFalse
に設定されています。
- ModelAdmin.search_fields
search_fields
を設定して、管理者変更リストページの検索ボックスを有効にします。 これは、誰かがそのテキストボックスで検索クエリを送信するたびに検索されるフィールド名のリストに設定する必要があります。これらのフィールドは、
CharField
やTextField
などの何らかのテキストフィールドである必要があります。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は次のSQLWHERE
句と同等の処理を行います。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は次のSQLWHERE
句と同等の処理を実行します。WHERE (first_name ILIKE '%john winston%' OR last_name ILIKE '%john winston%')
icontains
をルックアップとして使用したくない場合は、フィールドを追加することで任意のルックアップを使用できます。 たとえば、search_fields
を['first_name__exact']
に設定すると、:lookup: `exact` を使用できます。フィールドルックアップを指定するためのいくつかの(古い)ショートカットも利用できます。
search_fields
のフィールドの前に次の文字を付けることができます。これは、フィールドに__<lookup>
を追加するのと同じです。プレフィックス
調べる
^
=
@
なし
検索をカスタマイズする必要がある場合は、 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 のサブセットのlist
、tuple
、またはset
)。 空のコレクションは、すべての列の並べ替えを無効にします。このリストを動的に指定する必要がある場合は、代わりに get_sortable_by()メソッドを実装してください。
- ModelAdmin.view_on_site
view_on_site
を設定して、「サイトで表示」リンクを表示するかどうかを制御します。 このリンクをクリックすると、保存されたオブジェクトを表示できるURLに移動します。この値は、ブールフラグまたは呼び出し可能のいずれかです。
True
(デフォルト)の場合、オブジェクトの get_absolute_url()メソッドを使用してURLが生成されます。モデルに get_absolute_url()メソッドがあり、[サイトで表示]ボタンを表示したくない場合は、
view_on_site
をFalse
に設定するだけです。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()
メソッドには、削除するオブジェクトのHttpRequest
とQuerySet
が与えられます。 このメソッドをオーバーライドして、「選択したオブジェクトの削除」アクションの削除プロセスをカスタマイズします。
- 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
を返す必要があります。たとえば、
name
とage
で検索するには、次のように使用できます。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
メソッドには、編集中のHttpRequest
とobj
(または追加フォームのNone
)が与えられ、list
またはtuple
。
- ModelAdmin.get_prepopulated_fields(request, obj=None)
get_prepopulated_fields
メソッドには、編集中のHttpRequest
とobj
(または追加フォームの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
メソッドには、編集中のHttpRequest
とobj
(または追加フォームのNone
)が与えられ、フィールドのリストを返すことが期待されます。 ModelAdmin.exclude で説明されているように。
- ModelAdmin.get_fields(request, obj=None)
get_fields
メソッドには、編集中のHttpRequest
とobj
(または追加フォームのNone
)が与えられ、フィールドのリストを返すことが期待されます。上記の ModelAdmin.fields セクションで説明したように。
- ModelAdmin.get_fieldsets(request, obj=None)
get_fieldsets
メソッドには、編集中のHttpRequest
とobj
(または追加フォームの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
に渡され、コレクションを返すことが期待されます(例: 変更リストページでソート可能なフィールド名のlist
、tuple
、または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
メソッドには、編集中のHttpRequest
とobj
(または追加フォームの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
メソッドには、編集中のHttpRequest
とobj
(または追加フォームのNone
)が与えられ、反復可能なインラインを返すことが期待されます。 ModelAdmin.inlines で指定する代わりに、このメソッドをオーバーライドして、リクエストまたはモデルインスタンスに基づいてインラインを動的に追加できます。
- ModelAdmin.get_urls()
ModelAdmin
のget_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 をサブクラス化し、 fields や exclude などの属性で変更します。 したがって、たとえば、スーパーユーザーに追加のフィールドを提供したい場合は、次のように別の基本形式に交換できます。
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)
管理者がビューを追加および変更する際に使用する(
FormSet
、 InlineModelAdmin )ペアを生成します。たとえば、変更ビューでのみ特定のインラインを表示する場合は、次のように
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)
ModelAdmin
のformfield_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
ノート
ModelForm で
Meta.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
を返す場合、DisallowedModelAdminLookup
( SuspiciousOperation のサブクラス)が発生します。デフォルトでは、
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
を返す必要があります。obj
がNone
の場合、True
またはFalse
を返して、このタイプのオブジェクトの編集が一般に許可されているかどうかを示す必要があります(例: [ X151X]は、現在のユーザーがこのタイプのオブジェクトを編集することを許可されていないことを意味すると解釈されます)。
- ModelAdmin.has_delete_permission(request, obj=None)
obj
の削除が許可されている場合は、True
を返す必要があります。それ以外の場合は、False
を返します。obj
がNone
の場合、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)
ModelAdmin
のget_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
またはモデルインスタンスのリスト)の同種の反復可能であり、request
は HttpRequest です。このメソッドは、
(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を少し追加したい場合があります。 これは、ModelAdmin
でMedia
内部クラスを使用することで実現できます。
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
スーパークラスで定義されています)。 共有機能は次のとおりです。
form
fieldsets
fields
formfield_overrides
exclude
filter_horizontal
filter_vertical
ordering
prepopulated_fields
get_fieldsets()
get_queryset()
radio_fields
readonly_fields
raw_id_fields
formfield_for_choice_field()
formfield_for_foreignkey()
formfield_for_manytomany()
has_module_permission()
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によって自動的に作成されます。
次に、GroupAdmin
はmembers
フィールドを手動で除外する必要があります。 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)
Product
でImage
インスタンスの編集と作成を許可する場合は、 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.html
をtemplates/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_template 、 AdminSiteを変更することをお勧めします。 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_header
: AdminSite.site_headersite_title
: AdminSite.site_titlesite_url
: AdminSite.site_urlhas_permission
: AdminSite.has_permission()available_apps
:現在のユーザーが利用できるアプリケーションレジストリのアプリケーションのリスト。 リストの各エントリは、次のキーを持つアプリケーションを表すdictです。app_label
:アプリケーションラベルapp_url
:管理者のアプリケーションインデックスのURLhas_module_perms
:モジュールのインデックスページの表示とアクセスが現在のユーザーに許可されているかどうかを示すブール値models
:アプリケーションで利用可能なモデルのリスト
各モデルは、次のキーを持つdictです。
object_name
:モデルのクラス名name
:モデルの複数形の名前perms
:dict
追跡add
、change
、delete
、およびview
権限admin_url
:モデルの管理者変更リストURLadd_url
:新しいモデルインスタンスを追加するための管理URL
- AdminSite.has_permission(request)
- 指定された
HttpRequest
のユーザーが、管理サイトの少なくとも1つのページを表示する権限を持っている場合、True
を返します。 デフォルトでは、 User.is_active と User.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 サブクラスを参照します。
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)
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'
を配置する必要があります。
デフォルトの管理サイトを上書きする
カスタムAppConfig
の default_site 属性を、AdminSite
サブクラスまたは呼び出し可能オブジェクトのドット付きインポートパスに設定することで、デフォルトのdjango.contrib.admin.site
をオーバーライドできます。サイトインスタンスを返します。
from django.contrib import admin
class MyAdminSite(admin.AdminSite):
...
from django.contrib.admin.apps import AdminConfig
class MyAdminConfig(AdminConfig):
default_site = 'myproject.admin.MyAdminSite'
INSTALLED_APPS = [
...
'myproject.apps.MyAdminConfig', # replaces 'django.contrib.admin'
...
]
同じURLconf内の複数の管理サイト
同じDjangoを利用したWebサイトに管理サイトの複数のインスタンスを作成できます。 AdminSite
の複数のインスタンスを作成し、それぞれを異なるURLに配置します。
この例では、URL /basic-admin/
と/advanced-admin/
は、AdminSite
インスタンスmyproject.admin.basic_site
とmyproject.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
ログに記録されるアクションのタイプ:
ADDITION
、CHANGE
、DELETION
。たとえば、管理者を通じて行われたすべての追加のリストを取得するには、次のようにします。
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_id 、object_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): ...