models.pyでPOSTクラスのsaveメソッドをオーバライドする。urls.pyとviews.pyの設定こんにちは。この記事では、djangoのシグナル機能を使った事例を紹介します。具体的には、Djangoのあるテーブルレコードを新規登録した場合に、該当テーブルを外部参照しているようなテーブル側にも関連するレコードを自動的に登録させるといった事例でDjangoシグナルの使い方を説明したいと思います。Djangoシグナルとは?Django公式サイトには以下のように記載されています。Djangoには「シグナルディスパッチャ」が含まれています。これにより、フレームワークの別の場所でアクションが発生したときに、切り離されたアプリケーションに通知することができます。簡単に言うと、シグナルによって、特定の送信者が一連の受信者に何らかのアクションが実行されたことを通知できます。Signalsこれだけだとよくわかりづらいのですが、例えば、あるテーブルのレコードが変更されたことをシグナルとして通知メールを送信するといった使い方ができるようです。私もよく使い方がわからなかったのですが、具体的な事例で試してみましたので、実装方法をご紹介します。今回は、以下のような事例で実装してみました。「ブログに投稿記事を新規登録すると、関連するいいねテーブルのレコードを自動登録させる。」テーブルのモデルは以下のような構成です。Postテーブルのtitleを外部キーとしたいいねテーブルを実装するものとします。記事毎にいいねをカウントするレコードがGoodテーブルに存在しているという感じです。GoodレコードをPostテーブルと分ける必要があるのか?という点は今回は考慮しないものとします。Djangoのプロジェクト名はsample、アプリケーション名はapp1とします。models.pyの設定モデルの設定は以下の通り、Postクラスと、Goodクラスを定義します。str(self.title_name)この辺は特に難しい点はないかと思います。admin.pyの設定adminページ上から各テーブルのレコードを参照、操作できるようにadmin.pyに以下の設定をしておきます。GoodAdmin)ここまで設定したら、一旦マイグレーションとアクセス用のユーザIDを登録しておきます。runserverを実行してhttp://127.0.0.1:8000/adminにアクセスしてログオンします。以下のようにブログ記事と、いいね数のテーブルが表示されていればOKです。ブログ記事(Post)テーブルで1件、ブログ記事を登録してみます。Postテーブルを上記のように1件登録しても、いいねテーブル側にはレコードは登録されませんので、以下のように新規登録した投稿記事に関連するいいねレコードをマニュアルで登録する必要があります。このようなケースでは、登録したPost(記事)に紐づくいいねテーブル(Good)のレコードも自動的に登録されてほしいですよね。そんな時にDjangoのシグナルを使うと上記のような処理を実現することができます。以降が、具体的なシグナルの実装になります。models.pyでPOSTクラスのsaveメソッドをオーバライドする。新規登録されたPostテーブルのレコードのPK番号をリターンするようにsaveメソッドをオーバーライドします。str(self.title_name)models.Modelのsaveメソッドをオーバライドして、新規登録されたレコードのpk番号を取得(self.pk)し、context辞書変数に格納してreturnしてあげます。モデルの定義は以上です。今回は特に画面表示までは作りこみませんが、Djangoシグナルを利用する場合、urls.pyと参照先のビュー関数を何か定義しておかないとシグナルが正常に動作しなかったため以下のようなtop関数の定義を入れておきます。print("シグナルが実行されました。**kwargs):print("シグナルが実行されました。=contents["instance"])Good.objects.create(title_name=post_obj)@receiver以降がシグナルを実装している部分です。必要なメソッドを以下でインポートしています。receiver今回は、「モデルにデータが記録された後に実行されるシグナル」を実装したいので、シグナルの種類としてpost_saveをインポートします。モデルの定義とシグナルを関連付けたい場合は、以下のような形式で定義すればよいことになっています。**kwargs):今回は、Postクラスの新規レコードが登録されたことをシグナルとして処理を発動させたいので上記のようなコードにしています。signalmethod関数の中で発動させたい処理を定義しています。Pythonprint("シグナルが実行されました。Good.objects.create(title_name=post_obj)1234print("シグナルが実行されました。=contents["instance"])Good.objects.create(title_name=post_obj)何をやっているかというと、1行目は単純にシグナルが発動したことを確認するためにprintしているだけです。2行目では、内包表記を使ってkwargsに渡ってきた情報をcontents辞書型変数に格納しています。kwargsにはmodels.pyのsaveメソッドでreturnしたcontextが格納されているので、kwargs.itemsでキー、値を取得できます。※今回はpkだけですが、ほかの値も渡せばいろいろ受け取ることができます。contents["instance"]のように指定することで、新規登録されたPostクラステーブルの記事名(title_name)を取得することができます。今回は、登録された記事の情報が欲しいのでinstanceキーの値をcontents["instance"]として取得しています。取得した記事名をもとにPostテーブルから該当記事のレコードオブジェクトを取得しpost_objとして格納しています。post_objを使って、いいねテーブルに該当記事のレコードを登録しているのが以下の部分です。PythonGood.objects.create(title_name=post_obj)1Good.objects.create(title_name=post_obj)ちょっとわかりづらいかもしれませんが、以上でPostテーブルに対して記事を新規追加すると、関連するGoodテーブルのレコードが自動生成されるようになります。Postで新規にタイトル「記事2」を追加すると・・・いいねテーブルにも以下のようにPostテーブルに新規追加したレコードを外部キーとしたいいねテーブルレコードが自動的に登録されます。ちなみにviews.pyに渡されてくるcontents変数の中身をすべて確認すると以下のような情報が渡ってくるのが確認できます。'default'}本記事の作成に当たり以下のブログを参考にさせていただきました。Djangoシグナルの使い方を分かりやすく解説【サンプルコード付き】https://codor.co.jp/django/about-signalあるテーブルレコードが登録された場合にxxを実施したいというケースでいろいろと応用が利きそうですね。以上、Djangoでテーブル登録完了時に追加処理を行いたい場合の事例紹介でした。FacebookTwitterGoogle+はてブPocketFeedlyこの記事を書いた人siny現在の仕事は社内SEのお仕事です。趣味でDjango,Python,機械学習、ディープラーニングなどをやってます。【python】pandasのちょっとマニアックな使い方Djangoでファイル一覧情報を更新する方法おすすめの記事DeapLearningオートエンコーダを用いた時系列データ異常検知への応用こんにちは。以前、以下の記事でスパースオートエンコーダモデルで時系列データの異常検知を試してみましたが、1入力、1出力という...PythonPythonのpdfminerでPDFからテキスト情報抽出が簡単だったこんにちは。管理人のsinyです。この記事はDjango入門者向けのチュートリアルです。Django入門者向けにDjango開発を始め...Djangoディープラーニング+Djangoで言語翻訳デモアプリの作成【後編】こんにちは。この記事は、下記記事【ディープラーニング+Djangoで言語翻訳デモアプリの作成【後編】】の後編です。Seq...PythonPythonの正規表現テクニックまとめこんにちは。この記事ではpythonの正規表現を使ったテクニックに関するまとめ記事です。対数の2つのメリットを解説!こんにちは。対数(log)はディープラーニングの根幹でもある逆誤差伝搬などでも利用されていますが、対数を扱うことによる2つの...Python不動産データ分析事例【pythonデータ前処理編】こんにちは。本記事では、前回の下記で収集した中古不動産情報に対してデータ分析をするために各種前処理を行っていきます。notebookを使う方法こんにちは。Notebookを利用する方法を紹介します。