2010-04-16 12 views
8

試圖以最簡潔的方式添加電子郵件通知到我的應用程序。當模型的某些字段發生更改時,應用程序應向用戶發送通知。這裏是我的老辦法:它是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大小和我可以啓用/禁用單獨他們。缺點是這種解決方案是更多的代碼和信號處理程序與模型本身分開,而不知情的讀者可能完全錯過它們。所以,同事們,你認爲這是值得的嗎?

回答

3

我認爲在這裏使用信號是一個很好的設計決策。通知不是保存的一部分,這是保存的結果。處理這些類型的後果是Django提供信號的原因。

相關問題