📡

Django Signals — イベントベースの疎結合

post_save、pre_deleteが内部的にどう動くか

内部実装

django.dispatch.Signalは内部にreceiversリストを持つ。connect()で関数を登録、send()で全登録関数を順次呼び出し。

post_save.send()Model.save()内部で呼ばれる。

なぜ注意が必要か

  1. 暗黙的実行 — 明示的呼び出しがコードにないため「誰がこれを呼んでいる?」
  2. 順序保証なし — receiver実行順序は登録順に依存するが保証ではない
  3. トランザクション問題 — post_saveはトランザクションコミット前に実行される可能性。transaction.on_commit()使用推奨
  4. テスト複雑性 — Signalがテストでも発動し予期せぬ副作用

代替案:明示的サービス関数呼び出しの方が追跡しやすい。Signalは「アプリ境界を跨ぐ疎結合」が必要な時だけ。

キーポイント

1

Signal.connect()でreceiver関数を登録

2

Model.save()内部でpost_save.send()呼び出し→登録済みreceiver全て実行

3

receiverはsender、instance、created等の引数を受け取る

4

トランザクション安全のためtransaction.on_commit()内で処理推奨

ユースケース

ユーザー作成時プロフィール自動生成 注文完了時通知送信(アプリ間疎結合)

参考資料