試圖以最簡潔的方式添加電子郵件通知到我的應用程序。當模型的某些字段發生更改時,應用程序應向用戶發送通知。這裏是我的老辦法:它是approproate它在同一個應用程序內使用Django信號
from django.contrib.auth import User
class MyModel(models.Model):
user = models.ForeignKey(User)
field_a = models.CharField()
field_b = models.CharField()
def save(self, *args, **kwargs):
old = self.__class__.objects.get(pk=self.pk) if self.pk else None
super(MyModel, self).save(*args, **kwargs)
if old and old.field_b != self.field_b:
self.notify("b-changed")
# Sevelar more events here
# ...
def notify(self, event)
subj, text = self._prepare_notification(event)
send_mail(subj, body, settings.DEFAULT_FROM_EMAIL, [self.user.email], fail_silently=True)
這工作得很好,而我有一個或兩個通知類型,但在此之後只是覺得錯有這麼多的代碼在我save()
方法。所以,我改變代碼的信號爲基礎的:
from django.db.models import signals
def remember_old(sender, instance, **kwargs):
"""pre_save hanlder to save clean copy of original record into `old` attribute
"""
instance.old = None
if instance.pk:
try:
instance.old = sender.objects.get(pk=instance.pk)
except ObjectDoesNotExist:
pass
def on_mymodel_save(sender, instance, created, **kwargs):
old = instance.old
if old and old.field_b != instance.field_b:
self.notify("b-changed")
# Sevelar more events here
# ...
signals.pre_save.connect(remember_old, sender=MyModel, dispatch_uid="mymodel-remember-old")
signals.post_save.connect(on_mymodel_save, sender=MyModel, dispatch_uid="mymodel-on-save")
的好處是,我可以事件處理程序分離成不同的模塊,從而減少的models.py
大小和我可以啓用/禁用單獨他們。缺點是這種解決方案是更多的代碼和信號處理程序與模型本身分開,而不知情的讀者可能完全錯過它們。所以,同事們,你認爲這是值得的嗎?