web-dev-qa-db-ja.com

Djangoモデルでのシグナルの送受信

Django 2.0.8およびPython 3.5を使用しています。オブジェクトがデータベースに保存されたときにカスタムシグナルを送受信できるようにしたいです。

Djangoドキュメントを シグナルを聞く および Djangoにバンドルされているコアシグナル -をフォローしましたが、取得できません動作する例。

これは私がこれまでに持っているものです:

myapp/models.py

from Django.db import models
import Django.dispatch

my_signal = Django.dispatch.Signal(providing_args=["name"])

class Foo(models.Model):
    name = models.CharField(max_length=16)

def save(self, *args, **kwargs):
    try:
        # Call the "real" save() method.
        super().save(*args, **kwargs)  

        # Fire off signal         
        my_signal.send(sender=self.__class__, name=self.name)

    except Exception as e:
        print ('Exception:', e)
        #pass

myapp/signals.py

from Django.db.models.signals import post_save
from Django.dispatch import receiver
from .models import Foo


@receiver(post_save, sender=Foo)
def foo_handler(sender, **kwargs):
    print('Foo Signal Recieved!')
    print(kwargs)

myapp/app.py

class MyappConfig(AppConfig):
    name = 'myapp'
    label = 'myapp'

    def ready(self):
        import myapp.signals

使用例

from myapp.models import Foo

foo = Foo(name='Homer Simpson')
foo.save() # Object is saved, but event is not fired!

信号が発せられない理由を誰かが説明できますか?

Djangoが提供する2つの機能が必要なようです。 シグナル および コンテンツタイプ

したがって、最初にドキュメントを読んでください

モデルActivitycontenttypesに関連しており、object_idフィールドが欠落しているようです。これは、どのモデルインスタンスがクラッドされているかを示します。

すべてのcrudアクションに対して、Activityインスタンスが作成されています。この部分はsignal.pyに記述されたコードです。

signal:信号は各具象モデルを接続する必要があります。幸い、デコレータのソースコードを参照してください receiver

接続するシグナルリスト[post_save、post_delete]とモデルリスト(FoodooChile、FooBarChile)があります。

Post_saveで、引数createdは、アクションが作成または更新であることを示します。

最後に、通常、シグナルファイルをurls.pyにインポートしますが、ベストプラクティスではないかもしれません。


また、settings.pyにも関連しています。 'myapp.apps.MyappConfig'settings.pymyappに置き換え、またはdefault_app_config = 'myapp.apps.MyappConfig'myapp/__init__.pyを定義します。コメントの上のリンクはこれを詳細に説明しています

7
newlife
  1. _myapp.signals_には、post_saveシグナル(@receiver(post_save, sender=Foo))を処理するレシーバーがあり、シグナルに接続していません。
  2. アプリケーションの__ init __。pyでアプリ構成を使用していることを確認してください_default_app_config = 'myapp.apps.MyappConfig'_
  3. 作成したシグナルに接続するには、signals.pyファイルでこれを試してください。

    _@receiver(my_signal)
        def my_handler(name, **kwargs):
            print(name)
    _
0

あなたは車輪の再発明をしていますが、いわばカートの片側にしか置いていません。

post_saveシグナルは常に保存時に送信されるため、独自のシグナルを定義するのはやり過ぎです。そこに引数があることは知っていますが、レシーバーにはすでにsender引数があります。これは保存されたオブジェクトなので、sender.nameを実行するだけで、必要な値を取得できます。

それとは別に、構文エラーがあり、モデルのカスタム保存関数がインデントされていません。これがあなたの質問のフォーマットエラーなのか、それともコード内でどのように見えるのかわかりません。いずれにせよ、カスタム信号をドロップするだけで機能するはずです。

モデル

from Django.db import models
import Django.dispatch


class Foo(models.Model):
    name = models.CharField(max_length=16)

シグナル

from Django.db.models.signals import post_save
from Django.dispatch import receiver
from .models import Foo


@receiver(post_save, sender=Foo)
def foo_handler(sender, **kwargs):
    print(sender.name)

アプリ

class MyappConfig(AppConfig):
    name = 'myapp'
    label = 'myapp'

    def ready(self):
        import myapp.signals

サンプル

from myapp.models import Foo

foo = Foo(name='Homer Simpson')
foo.save()
0
firelynx