管理者のアクション
Djangoの管理者の基本的なワークフローは、一言で言えば、「オブジェクトを選択してから変更する」ことです。 これは、ほとんどのユースケースでうまく機能します。 ただし、一度に多くのオブジェクトに同じ変更を加える必要がある場合、このワークフローは非常に面倒な場合があります。
このような場合、Djangoの管理者は、「アクション」(変更リストページで選択されたオブジェクトのリストで呼び出される関数)を記述して登録することができます。
管理者の変更リストを見ると、この機能が動作していることがわかります。 Djangoには、すべてのモデルで利用できる「選択したオブジェクトの削除」アクションが付属しています。 たとえば、Djangoの組み込み django.contrib.auth アプリのユーザーモジュールは次のとおりです。
[[../File:../../../_images/admin-actions|../../../_images/admin-actions.png]]
警告
「選択したオブジェクトの削除」アクションは、効率上の理由から QuerySet.delete()を使用しますが、これには重要な注意事項があります。モデルのdelete()
メソッドは呼び出されません。
この動作をオーバーライドする場合は、 ModelAdmin.delete_queryset()をオーバーライドするか、任意の方法で削除を行うカスタムアクションを作成できます。たとえば、それぞれに対してModel.delete()
を呼び出します。選択したアイテム。
一括削除の背景については、オブジェクトの削除に関するドキュメントを参照してください。
このリストに独自のアクションを追加する方法については、以下をお読みください。
アクションを書く
アクションを説明する最も簡単な方法は例によるものなので、詳しく見ていきましょう。
管理アクションの一般的な使用例は、モデルの一括更新です。 Article
モデルのニュースアプリケーションを想像してみてください。
このようなモデルで実行する可能性のある一般的なタスクは、記事のステータスを「ドラフト」から「公開済み」に更新することです。 管理者で一度に1つの記事でこれを簡単に行うことができますが、記事のグループを一括公開する場合は面倒です。 それでは、記事のステータスを「公開済み」に変更できるアクションを作成しましょう。
アクション関数の記述
まず、管理者からアクションがトリガーされたときに呼び出される関数を作成する必要があります。 アクション関数は、次の3つの引数を取る通常の関数です。
- 現在の ModelAdmin
- 現在のリクエストを表す HttpRequest 、
- ユーザーが選択したオブジェクトのセットを含む QuerySet 。
これらの記事の公開関数は ModelAdmin またはリクエストオブジェクトを必要としませんが、クエリセットを使用します。
ノート
最高のパフォーマンスを得るには、クエリセットの更新メソッドを使用しています。 他のタイプのアクションでは、各オブジェクトを個別に処理する必要がある場合があります。 このような場合、クエリセットを繰り返し処理します。
実際には、アクションを作成するために必要なのはこれだけです。 ただし、オプションですが便利な手順をもう1つ実行し、管理者に「素敵な」タイトルを付けます。 デフォルトでは、このアクションは「公開する」としてアクションリストに表示されます。これは関数名であり、アンダースコアはスペースに置き換えられています。 それは問題ありませんが、make_published
関数の action()デコレータを使用することで、より適切で人間にわかりやすい名前を付けることができます。
ノート
これは見覚えがあるかもしれません。 管理者の list_display オプションは、 display()デコレータと同様の手法を使用して、そこに登録されているコールバック関数の人間が読める形式の説明も提供します。
バージョン3.2で変更: action()デコレータのdescription
引数は、前のアクション関数にshort_description
属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。
ModelAdmin へのアクションの追加
次に、 ModelAdmin にアクションを通知する必要があります。 これは、他の構成オプションと同じように機能します。 したがって、アクションとその登録を含む完全なadmin.py
は、次のようになります。
そのコードは、次のような管理者変更リストを提供します。
[[../File:../../../_images/adding-actions-to-the-modeladmin|../../../_images/adding-actions-to-the-modeladmin.png]] それが本当にすべてです! 独自のアクションを作成したい場合は、開始するのに十分な知識があります。 このドキュメントの残りの部分では、より高度な手法について説明します。
アクションのエラーの処理
アクションの実行中に発生する可能性のある予測可能なエラー状態がある場合は、問題をユーザーに適切に通知する必要があります。 これは、例外を処理し、 django.contrib.admin.ModelAdmin.message_user()を使用して、応答に問題のユーザーフレンドリーな説明を表示することを意味します。
高度なアクションテクニック
より高度なオプションに利用できる追加のオプションと可能性がいくつかあります。
ModelAdmin メソッドとしてのアクション
上記の例は、関数として定義されたmake_published
アクションを示しています。 これはまったく問題ありませんが、コード設計の観点からは完全ではありません。アクションはArticle
オブジェクトに緊密に結合されているため、アクションをArticleAdmin
オブジェクト自体にフックすることは理にかなっています。
あなたはこのようにそれを行うことができます:
最初にmake_published
をメソッドに移動し、modeladmin
パラメーターの名前をself
に変更し、次に文字列'make_published'
を配置したことに注意してください。直接関数参照の代わりにactions
で。 これは、 ModelAdmin にアクションをメソッドとして検索するように指示します。
アクションをメソッドとして定義すると、アクションは ModelAdmin 自体に慣用的にアクセスできるようになり、管理者が提供する任意のメソッドをアクションで呼び出すことができます。
たとえば、self
を使用して、アクションが成功したことを通知するメッセージをユーザーにフラッシュできます。
これにより、アクションが正常に実行された後、管理者自身が実行するアクションと一致します。
[[../File:../../../_images/actions-as-modeladmin-methods|../../../_images/actions-as-modeladmin-methods.png]]
中間ページを提供するアクション
デフォルトでは、アクションが実行された後、ユーザーは元の変更リストページにリダイレクトされます。 ただし、一部のアクション、特により複雑なアクションでは、中間ページを返す必要があります。 たとえば、組み込みの削除アクションは、選択したオブジェクトを削除する前に確認を求めます。
中間ページを提供するには、アクションから HttpResponse (またはサブクラス)を返します。 たとえば、Djangoのシリアル化関数を使用して、選択したオブジェクトをJSONとしてダンプするエクスポート関数を作成できます。
一般的に、上記のようなものは素晴らしいアイデアとは見なされません。 ほとんどの場合、ベストプラクティスは、 HttpResponseRedirect を返し、ユーザーを作成したビューにリダイレクトして、選択したオブジェクトのリストをGETクエリ文字列に渡すことです。 これにより、中間ページに複雑なインタラクションロジックを提供できます。 たとえば、より完全なエクスポート機能を提供したい場合は、ユーザーがフォーマットを選択できるようにし、場合によってはエクスポートに含めるフィールドのリストを選択できるようにします。 最善の方法は、カスタムエクスポートビューにリダイレクトする小さなアクションを作成することです。
ご覧のとおり、アクションはかなり短いです。 すべての複雑なロジックは、エクスポートビューに属します。 これは、あらゆるタイプのオブジェクトを処理する必要があるため、ContentType
を使用します。
このビューを書くことは、読者の練習問題として残されています。
アクションをサイト全体で利用できるようにする
- AdminSite.add_action(action, name=None)
一部のアクションは、管理サイトの任意のオブジェクトで使用できるようになっている場合に最適です。上記で定義したエクスポートアクションが適しています。 AdminSite.add_action()を使用して、アクションをグローバルに使用可能にすることができます。 例えば:
これにより、
export_selected_objects
アクションが「export_selected_objects」という名前のアクションとしてグローバルに使用できるようになります。 AdminSite.add_action()に2番目の引数を渡すことで、アクションに明示的に名前を付けることができます(後でプログラムでアクションを削除する場合に適しています)。
アクションを無効にする
特定のオブジェクトに対して、特定のアクション、特にサイト全体で登録されたを無効にする必要がある場合があります。 アクションを無効にできる方法はいくつかあります。
サイト全体のアクションを無効にする
- AdminSite.disable_action(name)
サイト全体のアクションを無効にする必要がある場合は、 AdminSite.disable_action()を呼び出すことができます。
たとえば、このメソッドを使用して、組み込みの「選択したオブジェクトの削除」アクションを削除できます。
上記を実行すると、そのアクションはサイト全体で利用できなくなります。
ただし、特定のモデルに対してグローバルに無効化されたアクションを再度有効にする必要がある場合は、
ModelAdmin.actions
リストに明示的にリストしてください。
特定の ModelAdmin のすべてのアクションを無効にする
特定の ModelAdmin で no バルクアクションを使用できるようにする場合は、 ModelAdmin.actions をNone
に設定します。
これは、 ModelAdmin に、サイト全体のアクションを含むアクションを表示または許可しないように指示します。
アクションを条件付きで有効または無効にする
- ModelAdmin.get_actions(request)
最後に、 ModelAdmin.get_actions()をオーバーライドすることで、リクエストごとに(したがって、ユーザーごとに)アクションを条件付きで有効または無効にできます。
これにより、許可されたアクションのディクショナリが返されます。 キーはアクション名であり、値は
(function, name, short_description)
タプルです。たとえば、名前が「J」で始まるユーザーのみがオブジェクトを一括で削除できるようにする場合は、次のようにします。
アクションの権限を設定する
アクションは、アクション関数を action()デコレータでラップし、permissions
引数を渡すことにより、特定の権限を持つユーザーに可用性を制限する場合があります。
make_published()
アクションは、 ModelAdmin.has_change_permission()チェックに合格したユーザーのみが使用できます。
permissions
に複数の権限がある場合、ユーザーが少なくとも1つのチェックに合格している限り、アクションを使用できます。
permissions
および対応するメソッドチェックに使用できる値は次のとおりです。
'add'
: ModelAdmin.has_add_permission()'change'
: ModelAdmin.has_change_permission()'delete'
: ModelAdmin.has_delete_permission()'view'
: ModelAdmin.has_view_permission()
ModelAdmin
に対応するhas_<value>_permission(self, request)
メソッドを実装する限り、他の値を指定できます。
例えば:
バージョン3.2で変更: action()デコレータのpermissions
引数は、前のアクション関数にallowed_permissions
属性を直接設定するのと同じです。バージョン。 下位互換性のために、属性を直接設定することは引き続きサポートされています。
actionデコレータ
- action(*, permissions=None, description=None)
バージョン3.2の新機能。
このデコレータは、アクションで使用できるカスタムアクション関数に特定の属性を設定するために使用できます。
これは、関数にいくつかの属性(元の長い名前を使用)を直接設定することと同じです。
このデコレータの使用は、アクション関数を作成するために必須ではありませんが、関数の目的を識別するためのソースのマーカーとして引数なしで使用すると便利な場合があります。
この場合、関数に属性は追加されません。