我正在尝试编写一些代码,每当其中一个用户修改模型对象时,该代码就会发送电子邮件。目前,我正在使用models.py中的一个方法接收post_save信号。我意识到,众所周知,post_save信号通常发送两次,因此,解决方法是使用dispatch_uid参数。我这样做了,但由于一些奇怪的原因,我继续收到两个信号。这是我的应用程序的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'
我已经多次重启服务器,重置/删除应用程序的所有数据,我仍然继续收到两个信号。我的代码有什么固有的错误吗?任何建议或见解将不胜感激!谢谢!
答案 0 :(得分:1)
您的问题来自于每次通过管理界面修改对象时,admin app会创建代表所做更改的django.contrib.admin.models.LogEntry实例。
因为你正在所有对象上监听post_save,所以你的监听器被调用两次 - 一次是你的模型,第二次是LogEntry模型。
可能的解决方案列表包括:
使用post_save方法中的 sender 参数,为每个模型单独注册监听器(例如,以某种方式选择模型并循环执行)。
for model in get_models():
post_save.connect(send_email, sender = model, dispatch_uid='unique_identifier')
检查发送给侦听器的 sender 是否不是django.contrib.admin.models.LogEntry的实例
from django.contrib.admin.models import LogEntry
...
def send_email(sender, **kwargs):
if isinstance(sender, LogEntry):
return
为您的模型提供一个共同的超类,并将其用于在侦听器中进行测试
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