2010-04-16 2 views
8

Попытка добавления уведомления по электронной почте в мое приложение самым чистым способом. Когда определенные поля модели меняются, приложение должно отправить уведомление пользователю. Вот мое старое решение:Согласен ли он использовать сигналы 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 и включить/отключить их по отдельности. Недостатком является то, что это решение больше кода, а обработчики сигналов отделены от самой модели, и незнакомый читатель может вообще пропустить их. Итак, коллеги, вы думаете, это того стоит?

ответ

4

Я думаю, что это хорошая идея. "Custom Signals for Uncoupled Design" talk от самого последнего DjangoCon - отличный ресурс того, что возможно и подходит с сигналами в Django.

3

Я думаю, что использование сигналов здесь хорошее дизайнерское решение. Уведомление не является частью сохранения, это следствие сохранения. Причиной использования этих типов последствий является то, что Django предоставляет сигналы.

Смежные вопросы