• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar
  • Skip to footer

AI活用エンジニアへの道

生成AI時代のエンジニアの生き方を考えるメディア(作成途中)

  • コラム
  • 生成AI
  • プログラミング
    • Python入門
    • Flask入門
    • Django入門
  • プロフィール
Home / プログラミング / Django / DjangoでModelのsave前後で処理を行うSignalのpre_save, post_saveの使い方

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

1 pre_save, post_saveの詳細・定義の方法
2 pre_save, post_saveの定義の方法2
3 関連記事

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)

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

  • models.pyの定義
class PostModel(models.Model):
    id = models.BigAutoField(primary_key=True)
    active = models.BooleanField(blank=True)
    title = models.CharField(max_length=240)
    slug = models.SlugField(null=True, blank=True)
    content = models.TextField(null=True, blank=True)

def blog_post_model_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug and instance.title:
        instance.slug = slugify(instance.title)

pre_save.connect(blog_post_model_pre_save_receiver, sender=PostModel)
# pre_saveをPostModelモデルに設定しする。
# 保存前にオブジェクトのtitleが出力され、slugが設定される

また、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の定義
def blog_post_model_post_save_receiver(sender, instance, created, *args, **kwargs):
    if created:
        if not instance.slug and instance.title:
            instance.slug = slugify(instance.title)
            instance.save()

post_save.connect(blog_post_model_post_save_receiver, sender=PostModel)
# receiver, senderを設定、modelのsave後に、blog_post_model_post_save_receirverが呼び出される

同様にpost_saveの設定を外すにはdisconnectを利用する

post_save.disconnect(blog_post_model_post_save_receiver, sender=PostModel)


pre_save, post_saveの定義の方法2

pre_save, post_saveを登録する方法は、デコレータを使う方法もあり、簡潔に記載することができる

以下のように関数の上に@receiver(pre_save(or post_save),modelクラス)のように記載する。

  • pre_save, post_saveの設定方法2
from django.dispatch import receiver
from django.db.models.signals import post_save, pre_save

# PostModelのsave前に実行される
@receiver(pre_save, sender=PostModel)
def blog_post_model_pre_save_receiver(sender, instance, *args, **kwargs):
    if not instance.slug and instance.title:
        instance.slug = slugify(instance.title)

# PostModelのsave後に実行される
@receiver(post_save, sender=PostModel)
def blog_post_model_post_save_receiver(sender, instance, created, *args, **kwargs):
    if created:
        if not instance.slug and instance.title:
            instance.slug = slugify(instance.title)
            instance.save()

関連記事

現役エンジニアがDjangoに関する本を5つ紹介
現役エンジニアがDjangoに関する本を5つ紹介
WindowsでDjango、Anaconda、VSCodeのインストールとDjangoを開発する環境の構築をする
WindowsでDjango、Anaconda、VSCode…
MacでDjango、Anaconda、VSCodeのインストールとDjangoを開発する環境の構築をする
MacでDjango、Anaconda、VSCodeのインス…
DjangoのFormに初期値を設定する方法
DjangoのFormに初期値を設定する方法
DjangoのModelにSlugFieldを利用する。その利用方法と
DjangoのModelにSlugFieldを利用する。その…
Djangoのモデルの各フィールドについて解説(AutoField, BigAutoField, BooleanField, CharField, TextField, DateField, EmailField, IntegerField)
Djangoのモデルの各フィールドについて解説(AutoFi…

Primary Sidebar

人気記事

  • 1
    PyCharm,IntelliJのおすすめプラグイン一覧
  • no image 2
    Python未経験だが、フリーランスの案件に採用さ…
  • 3
    ITエンジニアとしてスキルを高めるためのUdemy講…
  • 4
    アメリカのシリコンバレーでプログラミングを無…

特集記事

  • 1
    Cursorの使用のポイントとコツ(コード補完、イ…
  • 2
    ITエンジニアとしてスキルを高めるためのUdemy講…

目次

1 pre_save, post_saveの詳細・定義の方法
2 pre_save, post_saveの定義の方法2
3 関連記事
StartCode ロゴ
AI時代のエンジニアを最速で育てる
法人向けIT研修で即戦力を育成しています。詳しくはお問い合わせください。
▶ 詳細はこちら
Django講座
【Udemy】Django入門講座(0からDjangoを学習: Python講座つき)
受講生6500人ほどの人気講座。<strong>View, Template, Model, Cla...
詳細 ▶

Footer

利用規約