【问题标题】:Django - send email on model changeDjango - 发送有关模型更改的电子邮件
【发布时间】:2010-11-12 16:48:25
【问题描述】:

我想在模型中的特定字段发生更改时发送电子邮件。可能吗?这就是我要找的东西。我有一个包含 BooleanField 的配置文件模型,当管理员选择为 true 时,我想向用户发送电子邮件。我知道我可以把它放在“def save(self):”中,但是,只要模型改变并且字段为真,就会触发一封电子邮件。如果字段从 False 更改为 True,有没有办法让它只通过电子邮件发送?

【问题讨论】:

    标签: django email model


    【解决方案1】:

    save 方法是您想要做的事情的绝佳选择:

    def save(self):
        if self.id:
            old_foo = Foo.objects.get(pk=self.id)
            if old_foo.YourBooleanField == False and self.YourBooleanField == True:
                send_email()
        super(Foo, self).save()
    

    【讨论】:

    • 我可能会将 if 语句更改为:if not old.field == self.field:
    • 他只想在值从 False 变为 True 时发送电子邮件。所以检查值不相等是不够的。
    • 正在寻找一种在模型更改时触发任何操作的方法......看起来就是这样。谢谢。
    • 在这里覆盖 save 的一个缺点是:send_email() 调用将被阻塞,直到它完成执行。在页面再次加载之前,用户可能需要等待一段不平凡的时间。如果这不是问题,那很好;否则,我建议使用下面提到的信号方法。
    • 在阅读了有关更改值的评论后,我撤回了有关信号方法的声明。另请参阅:stackoverflow.com/questions/1355150/… 查看 Josh 获得 > 20 票的答案。如果您认为发送邮件的等待时间可能是个问题,您可能想查看类似 django-celery-email 的内容。
    【解决方案2】:

    您可以使用django-model-changes 来执行此操作,而无需额外的数据库查找:

    from django.db import models
    from django.dispatch import receiver
    from django_model_changes import ChangesMixin
    
    class MyModel(ChangesMixin, models.Model):
       flag = models.BooleanField()
    
    @receiver(pre_save, sender=MyModel)
    def send_email_if_flag_enabled(sender, instance, **kwargs):
        if instance.previous_instance().flag == False and instance.flag == True:
            # send email
    

    【讨论】:

      【解决方案3】:

      这样的事情可能会有所帮助,并且只有在从 false 变为 true 时才会发送电子邮件

      #models.py
      from django.contrib.auth.models import User
      from django.db.models import signals
      from django.db import models
      from django.dispatch import receiver
      from django.db.models.signals import pre_save
      from django.conf import settings
      from django.core.mail import send_mail
      
      #signal used for is_active=False to is_active=True
      @receiver(pre_save, sender=User, dispatch_uid='active')
      def active(sender, instance, **kwargs):
          if instance.is_active and User.objects.filter(pk=instance.pk, is_active=False).exists():
              subject = 'Active account'
              mesagge = '%s your account is now active' %(instance.username)
              from_email = settings.EMAIL_HOST_USER
              send_mail(subject, mesagge, from_email, [instance.email], fail_silently=False)
      

      【讨论】:

        【解决方案4】:

        使用 django 信号 (http://docs.djangoproject.com/en/dev/ref/signals/#django.db.models.signals.post_save) 对模型 post_save 使用挂钩函数

        在该功能中使用标准 django 邮件:http://docs.djangoproject.com/en/dev/topics/email/

        【讨论】:

        • 您不会在 post_save 中保留旧值,因此无法知道该值是否实际发生了变化。
        猜你喜欢
        • 2012-04-04
        • 2011-10-18
        • 2012-07-18
        • 2010-11-23
        • 1970-01-01
        • 2018-03-02
        • 1970-01-01
        • 2016-09-28
        • 2017-05-17
        相关资源
        最近更新 更多