0
我們使用django-MPTT樹項目,當樹項目被修改時,我必須創建自動電子郵件通知的功能。絕對直接使用保存信號,但是 - 如果修改了父項,則n(n代表孩子數+父項)發送電子郵件,而不僅僅發送一次(因爲父母的更改會自動完成給孩子)。有沒有一種很好的方法來防止這種情況發生,並基本告訴Django「每個模型只能發送一封郵件」?如何讓Django每個模型只運行一次命令
最好的我想出了一種哈克的方式(和一個非常糟糕的破解):添加一個模型到數據庫中,當父項修改時更新,並且兒童總是先檢查該模型發送郵件。即如果HiddenModel
存在,請勿發送電子郵件,否則發送電子郵件。等5秒後(可能在另一個線程中)刪除/撤消對該對象的修改。這可能會起作用,但是在性能方面,這與所有這些數據庫查詢都是不好的。
編輯:型號:(縮短的版本爲SO,可能有這種形式的一些錯誤)
從mptt.models進口MPTTModel,TreeForeignKey
class TreeItem(MPTTModel):
parent = TreeForeignKey('self', null=True, blank=True, related_name='children')
users = models.ManyToManyField('accounts.User', blank=True)
name = models.CharField(max_length=255)
@property
def tree_path(self):
if self.is_root_node():
return []
tree = self.get_ancestors(include_self=False, ascending=False)
return list(map(lambda item: item.name, tree))
def save(self, *args, **kwargs):
is_new = self.pk is None
if not is_new:
prev_allowed_users = TreeItem.objects.get(pk=self.pk).users.all()
super().save(*args, **kwargs)
new_allowed_users = self.users.all()
if is_new:
self.send_access_email(list(new_allowed_users)) #TODO
else:
if prev_allowed_users != new_allowed_users:
send_to = self.get_new_access_users(prev_allowed_users, new_allowed_users) # TODO
self.send_access_email(send_to)
def get_new_access_users(self, prev_users, new_users):
send_to = []
for user in new_users:
if user not in prev_users:
send_to.append(user)
return send_to
def send_access_email(self, recipient_list):
email_content = 'example'
email = EmailMessage(
'subject',
email_content,
'[email protected]',
recipient_list)
print("Sending email to %s users" % str(len(recipient_list)))
你可以發佈你的模型?我想我可以非常直觀地描述你所描述的內容,但總是有助於將它展現在我面前。 – Travis
@Travis更新了問題。 – makaveli
如果使用實際的post_save信號而不是重寫save()方法,它是否仍然傳播給所有的孩子? –