2

ユーザーの 1 人がモデル オブジェクトを変更するたびに電子メールを送信するコードを作成しようとしています。現在、models.py のメソッドの 1 つが post_save シグナルを受信するように取り組んでいます。post_save シグナルが通常 2 回送信されることはよく知られている事実であるため、回避策は dispatch_uid パラメータを使用することです。これを実行しましたが、何らかの奇妙な理由で、引き続き 2 つの信号を受信します。これが私のアプリの model.py ファイルのコードです。

from django.db import models
from django.db.models.signals import post_save

def send_email(sender, **kwargs):
      print "Signal sent." #just a placeholder

post_save.connect(send_email, dispatch_uid="unique_identifier")

class Library_Associates (models.Model):
      first_name = models.CharField(max_length = 200)
      last_name = models.CharField(max_length = 200)

  department_choices = (
        ('ENG', 'Engineering'),
        ('ART', 'Arts and Sciences'),
        ('AFM', 'Accounting and Financial Managment'),
        ('MAT', 'Mathematics'),
  )

  department = models.CharField(max_length = 3, choices = department_choices, default = 'ENG')

  pub_date = models.DateTimeField ('date published')

  def __unicode__(self):
        return self.first_name

  class Meta:
        verbose_name_plural = 'Library Associates'

class Info_Desk_Staff (models.Model):
      first_name = models.CharField(max_length=50)
      last_name = models.CharField(max_length=50)
      salary = models.IntegerField()
      hours_worked = models.IntegerField()

      def __unicode__(self):
            return self.first_name

      class Meta:
            verbose_name_plural = 'Info Desk Staff'

サーバーを数回再起動し、アプリのすべてのデータをリセット/削除しましたが、引き続き 2 つの信号を受信して​​います。私のコードに本質的に何か問題がありますか? どんな提案や洞察も大歓迎です! ありがとう!

4

1 に答える 1

4

あなたの問題は、管理インターフェースを介してオブジェクトを変更するたびに、管理アプリが変更を表すdjango.contrib.admin.models.LogEntryインスタンスを作成するという事実から生じます。

すべてのオブジェクトで post_save をリッスンしているため、リスナーは 2 回呼び出されます。1 回目はモデル用、2 回目は LogEntry モデル用です。

可能な解決策のリストは次のとおりです。

  1. post_saveメソッドの送信者引数を使用して、モデルごとに個別にリスナーを登録します (たとえば、何らかの方法でモデルを選択し、ループで実行します) 。

    for model in get_models():
        post_save.connect(send_email, sender = model, dispatch_uid='unique_identifier')
    
  2. リスナーに送信された送信者が django.contrib.admin.models.LogEntry のインスタンスではないかどうかを確認します

    from django.contrib.admin.models import LogEntry
    ...
    
    def send_email(sender, **kwargs):
        if isinstance(sender, LogEntry):
            return
    
  3. モデルに共通のスーパー クラスを与え、それをリスナーでのテストに使用する

    class MyModel(models.Model):
        pass
    
    class Library_Associates (MyModel):
        ...
    class Info_Desk_Staff (MyModel):
        ...
    
    def send_email(sender, **kwargs):
        if not isinstance(sender, MyModel):
            return
    
于 2013-02-07T15:23:58.610 に答える