LoginSignup
26
8

More than 3 years have passed since last update.

Django Signalsの種類と使い方

Last updated at Posted at 2020-10-23

概要

Signalsとは

データが更新されたり、リクエストが起きた時が起きた時に処理を走らせることができる。
例えば、データが作成されたことをお知らせしたい時や他のデータもついでに作成したい時なんかに便利。

Django 公式ドキュメント

どこに書けばいいの?

公式サイトよると

Strictly speaking, signal handling and registration code can live anywhere you like, although it's recommended >to avoid the application's root module and its models module to minimize side-effects of importing code.

In practice, signal handlers are usually defined in a signals submodule of the application they relate to. >Signal receivers are connected in the ready() method of your application configuration class. If you're using >the receiver() decorator, import the signals submodule inside ready().

全く意味は分かりませんが、どうやらサブモジュールに定義するといいらしい。
ってことでsignals.pyを作った!

種類

何ができるんだろう

名前 意味
pre_init モデルをインスタンス化した最初
post_init モデルをインスタンス化した最後
pre_save モデルのsave()メソッドの最初
post_save モデルのsave()メソッドの最後
m2m_changed 中間テーブルの変更
pre_migrate migrateを実行する前
post_migrate migrateを実行した後
request_started HTTPリクエストを応答した最初
request_finished HTTPリクエストを応答した最後
got_request_exception HTTPリクエスト中に例外が発生したら
connection_created DBの接続が開始されたら

Django 公式サイトにはまだいくつか種類があったけど眠い。(現在 AM 2:38)😃😃

使い方

Djangoにreceiverを認識しもらうために下準備が必要。
ちなみに今回のアプリケーションの名前はbookという謎な名前です😃😃😃

AppConfigに準備

settings.pyにAppConfigを参照しておく😃😃

settings.py
DJANGO_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
THIRD_PARTY_APPS = [
    'rest_framework',
    'django_filters',
]

LOCAL_APPS = [
    'common.apps.CommonConfig',
    'book.apps.BookConfig', # <- こいつ
]

INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS

app.pyにsignals.pyをimportする必要がある😃😃😃

book/apps.py

from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _


class BookConfig(AppConfig):
    name = 'book'
    verbose_name = _('Book')

    def ready(self):
        try:
            import book.signals
        except ImportError:
            pass

ってことで下準備が終わったので、signals.py
どんどん書いていこう~😃😃😃😃

receiverを書く

@receiverデコレータを書いて基本的なのは実行ができる☺️☺️

ってことでサンプルに、pre_saveの書きかた!!!!

book/signals.py

from django.db.models.signals import pre_save
from django.dispatch import receiver

from .models import Book


@receiver(pre_save, sender=Book)
def sample(sender, *args, **kwargs):
    print(sender, args, kwargs)

これでviews.pyとかでモデルオブジェクトをsave()した最後には
sample()が実行される。

book/views.py

class ListBook(APIView):

    def get(self, request):
        b = Book(# ゴニョゴニョいれる)
        b.save()
        return Response('success')

ってことで以上になります☺️☺️☺️☺️

26
8
1

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
26
8