I'm trying to write some code that sends an email every time one of the users modifies a model object. Currently, I'm working on having the one of the methods in models.py receive a post_save signal. I realize it's a well known fact that the post_save signal is usually sent twice, thus, the workaround is to utilize the dispatch_uid parameter. I have done this, but for some strange reason, I continue to receive two signals. Here's the code in my app's model.py file.
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'
I already restarted the server several times, reset/deleted all the data for the app and I continue to still receive two signals. Is there something inherently wrong with my code? Any suggestions or insight would be greatly appreciated! Thanks!
Your problem comes from the fact that each time you modify an object via the admin interface, admin app creates the django.contrib.admin.models.LogEntry instance that represents changes made.
Because you are listening to post_save on all objects, your listener is called twice - once for your model, and the second time for the LogEntry model.
List of possible solutions includes:
Registering your listener separately for each of your models (e.g. select your models somehow and do it in a loop) using the sender argument in the post_save method.
for model in get_models():
post_save.connect(send_email, sender = model, dispatch_uid='unique_identifier')
Check if the sender sent to the listener is not an instance of django.contrib.admin.models.LogEntry
from django.contrib.admin.models import LogEntry
...
def send_email(sender, **kwargs):
if isinstance(sender, LogEntry):
return
Give your models a common super class and use that for testing in the listener
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With