Django

DjangoでModelのsave前後で処理を行うSignalのpre_save, post_saveの使い方

DjangoのSignalとは、フレームワーク内でアクションが発生した際に処理が発生する仕組みです。以下のようなSignalです。

pre_save
post_save
モデルのsave()メソッドが実行される前後に実行されます。
(本記事で詳細を説明します)
pre_save
post_save
モデルのdelete()メソッド、QuerySetのdelete()メソッドが実行される前後で実行されます。
m2m_changed モデルのManyToManyが変更されたときに呼び出されます。
request_started
request_finished
DjangoがRequestを処理する前後で呼び出されます
pre_save, post_saveの詳細・定義の方法

per_saveは、modelのsave()メソッド処理の前に呼び出されます。

以下の引数を持ちます
sender: モデルクラス
instance: 保存されたインスタンス
pre_save用の関数を、以下のように定義します。

そして、django.db.models.signals.presave.connect()でモデルにpre_saveに登録設定します

def blog_post_model_pre_save_receiver(sender, instance, *args, **kwargs):
# sender, instance, *args, **kwargsを引数として持ちます。

from django.db.models.signals import pre_save

pre_save.connect(blog_post_model_pre_save_receiver, sender=PostModel)

実際にコードは以下のように記載します。

また、pre_saveの設定を外すには、disconnectメソッドを利用します。

pre_save.disconnect(blog_post_model_pre_save_receiver, sender=PostModel)

同様にmodelのsave()後に実行するようにシグナルを設定するのは、post_saveを利用します。

以下の引数を持ちます
sender: モデルクラス
instance: 保存されたインスタンス
created: レコードが新たに作成されたときにTrueを返すブール値
pre_save用の関数を、以下のように定義します。

そして、django.db.models.signals.post_save.connect()でモデルにpost_saveに登録設定します

def blog_post_model_post_save_receiver(sender, instance, created, *args, **kwargs):
# sender, instance, created, *args, **kwargsを引数として持ちます。

from django.db.models.signals import post_save

post_save.connect(blog_post_model_post_save_receiver, sender=PostModel)

実際にコードは以下のように記載します。

同様にpost_saveの設定を外すにはdisconnectを利用します。

post_save.disconnect(blog_post_model_post_save_receiver, sender=PostModel)

BooleanField

pre_save, post_saveを登録する方法は、デコレータを使う方法もあります。こちらの方法の方が簡潔に記載することができ、使いやすいかもしれません。

以下のように関数の上に@receiver(pre_save(or post_save),modelクラス)のように記載します。以下サンプルコードです。