1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Djangoのシグナル: 効果的なイベントハンドリング

Last updated at Posted at 2024-01-22

こんにちは!
AXLBIT株式会社@yangです。

今回はDjangoのシグナルについてお話します。

Djangoは、信頼性の高いウェブアプリケーションを構築するための強力なフレームワークです。その中でも、シグナルは非常に重要であり、イベント駆動型のプログラミングにおいて非常に有用です。

Djangoのシグナル

Djangoには「シグナルディスパッチャー」と呼ばれる仕組みが組み込まれており、これは切り離されたアプリケーションがフレームワークの他の場所でアクションが発生した際に通知を受けるのに役立ちます。要するに、シグナルは特定の送信者が一連のレシーバに対して、あるアクションが発生したことを通知することを可能にします。これは同じイベントに関心を持つ多くのコードが存在する場合に特に役立ちます。

Djangoの組み込みシグナルは、ユーザーコードに特定のアクションが発生したことを通知する機能を提供しています。

また、独自のカスタムシグナルを定義して送信することもできます。

シグナルの主な用途

Djangoのシグナルは以下のような用途で活用されます。

モデルの変更の検知

モデルのインスタンスが保存、更新、削除されたときにSignalを使用してそれを検知し、必要な処理を実行します。

ユーザー認証の拡張

ユーザーがログインまたはログアウトしたときにSignalを使用して、特定のアクションを実行する。

アクションの起動装置

アプリケーション内の異なるコンポーネント間での特定のアクションの起動装置としてSignalを使用する。

シグナルの使い方

シグナルを受信するためには、Signal.connect() メソッドを使用してレシーバー関数を登録します。レシーバー関数はシグナルが送信されたときに呼び出されます。シグナルのすべてのレシーバー関数は、登録された順序で一度に1つずつ呼び出されます。

レシーバー関数を定義

レシーバー関数は以下のように定義されます。

def my_callback(sender, **kwargs):
    処理

レシーバー関数も非同期処理として定義できます、その場合はdefの前にasyncをつければ良いです。

レシーバー関数を接続

レシーバー関数を接続する際二つの方法があります。

その一つは以下のように手動で接続させます。

from django.core.signals import シグナル名
シグナル名.connect(レシーバー関数)

もしくは、receiverデコレーターを使用することもできます。

from django.core.signals import シグナル名
from django.dispatch import receiver


@receiver(シグナル名)
def レシーバー関数名(sender, **kwargs):
    処理

これでこのレシーバー関数は指定のシグナルが発生するたびに実行されます。

特定の送信者から送られたシグナルに接続

receiverにさらにsenderを指定することで、特定の送信者からのシグナルのみに反応するようにもできます。

from django.db.models.signals import シグナル名
from django.dispatch import receiver
from アプリ名.models import モデル名


@receiver(シグナル名, sender=モデル名)
def レシーバー関数名(sender, **kwargs):
    処理

使い方について、こちらのページでご確認ください。

よく使われるシグナル

Djangoでは多くのビルトインシグナルが提供されています。

以下によく使われるシグナルの実行タイミングとそれを使う際のレシーバー関数の引数の**kwargsとして使えるものをまとめています。

シグナル名 実行タイミング レシーバー関数引数
pre_init インスタンス初期化前 args:クラスのコンストラクタに渡される引数
kwargs:クラスのコンストラクタに渡されるキーワード引数
post_init インスタンス初期化後 instance:作成されたインスタンス
pre_save モデル保存前 instance:保存されるモデルのインスタンス
raw:loaddatadeferを使用している場合はTrue
using:データベースエイリアスの名前
post_save モデル保存後 instance:保存されたモデルのインスタンス
created:新しいレコードが作成された場合はTrue
raw:loaddatadeferを使用している場合はTrue
using:データベースエイリアスの名前
pre_delete モデル削除前 instance:削除されるモデルのインスタンス
using:データベースエイリアスの名前
post_delete モデル削除後 instance:削除されたモデルのインスタンス
using:データベースエイリアスの名前
m2m_changed Many-to-Many 変更時 instance:関連するモデルのインスタンス
action:追加、削除、クリアのいずれか
reverse:逆の関係フィールドを通している場合はTrue
model:対象のMany-to-Manyフィールドのクラス
pk_set:変更後の関連付けられた主キーのセット
using:データベースエイリアスの名前
class_prepared クラスが初めて読み込まれる
pre_migrate マイグレーション前 using:データベースエイリアスの名前
plan:マイグレーションの実行計画
post_migrate マイグレーション後 using:データベースエイリアスの名前
plan:マイグレーションの実行計画
request_started リクエスト開始時 environ:環境変数
request_finished リクエスト完了時
got_request_exception リクエスト例外時 request:HttpRequestオブジェクト
setting_changed 設定変更時 setting:変更された設定のキー
value:新しい値
enter:設定が変更される前に存在したかどうか
setting_changed:設定変更のスタック
template_rendered テンプレートレンダリング時 template:レンダリングされたテンプレートのパス
context:テンプレートに渡されたコンテキスト
connection_created データベース接続時 connection:作成されたデータベース接続

使えるシグナルについて、こちらのページでご確認ください。

まとめ

Djangoのシグナルを活用することで、アプリケーションの機能を拡張し、柔軟性を高めることができます。 シグナルはDjangoアプリケーションの中で強力なツールであり、正しく使用することでコードの保守性と拡張性を向上させることができます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?