简体   繁体   English

它是否适用于在同一个应用程序中使用django信号

[英]Is it approproate it use django signals within the same app

Trying to add email notification to my app in the cleanest way possible. 尝试以最干净的方式向我的应用添加电子邮件通知。 When certain fields of a model change, app should send a notification to a user. 当模型的某些字段发生变化时,应该向用户发送通知。 Here's my old solution: 这是我的旧解决方案:

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)

This worked fine while I had one or two notification types, but after that just felt wrong to have so much code in my save() method. 这个工作正常,而我有一个或两个通知类型,但之后在我的save()方法中有这么多代码感觉不对。 So, I changed code to signal-based: 所以,我将代码更改为基于信号:

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")

The benefit is that I can separate event handlers into different module, reducing size of models.py and I can enable/disable them individually. 好处是我可以将事件处理程序分成不同的模块,减少models.py大小,我可以单独启用/禁用它们。 The downside is that this solution is more code and signal handlers are separated from model itself and unknowing reader can miss them altogether. 缺点是这个解决方案是更多的代码和信号处理程序与模型本身分开,不知情的读者可以完全错过它们。 So, colleagues, do you think it's worth it? 所以,同事们,你觉得它值得吗?

I think it's a good idea. 我认为这是个好主意。 The "Custom Signals for Uncoupled Design" talk from the most recent DjangoCon is a great resource of what is possible and appropriate with signals in Django. 最新的DjangoCon中的“Unagoupled Design的自定义信号”讲话是Django中信号可能和适当的重要资源。

I think using signals here is a good design decision. 我认为在这里使用信号是一个很好的设计决策。 The notification isn't part of the save, it's a consequence of the save. 通知不是保存的一部分,它是保存的结果。 Dealing with these types of consequences is the reason Django provides signals. 处理这些类型的后果是Django提供信号的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM