【问题标题】:How can I send an email based on a new primary key being generated through Django?如何根据通过 Django 生成的新主键发送电子邮件?
【发布时间】:2013-07-24 19:09:47
【问题描述】:

每当在 Django 中生成新的主键时,我想向用户发送一封电子邮件。我在 Models.py 中的代码:

class PurchaseOrder(models.Model):
    product = models.CharField(max_length=256)
    vendor = models.CharField(max_length=256)
    dollar_amount = models.FloatField()
    item_number = models.AutoField(primary_key=True)

我已将其编码到每次刷新页面时都可以发送电子邮件的位置

email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
email.send()

但我怎样才能让每次生成新的主键时,发送一封电子邮件?

【问题讨论】:

    标签: python django email key


    【解决方案1】:

    使用django signals

    from django.db.models import signals
    
    def send_email_on_new_order(instance, created, raw, **kwargs):
        # Fixtures or updates are not interesting.
        if not created or raw:
            return
    
        # `instance` is your PurchaseOrder instance.
        email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
        email.send()
    
    signals.post_save.connect(send_email_on_new_order, sender=PurchaseOrder, dispatch_uid='send_email_on_new_order')
    

    您必须将此代码粘贴到将在加载 django 期间执行的某个位置,例如models.py

    例如models.py:

    from django.core.mail import EmailMessage
    from django.db import models
    from django.db.models import signals
    
    class PurchaseOrder(models.Model):
        product = models.CharField(max_length=256)
        vendor = models.CharField(max_length=256)
        dollar_amount = models.FloatField()
        item_number = models.AutoField(primary_key=True)
    
    def send_email_on_new_order(instance, created, raw, **kwargs):
        # Fixtures or updates are not interesting.
        if not created or raw:
            return
    
        # `instance` is your PurchaseOrder instance.
        email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
        email.send()
    
    signals.post_save.connect(send_email_on_new_order, sender=PurchaseOrder, dispatch_uid='send_email_on_new_order')
    

    【讨论】:

    • 我收到一条错误消息,提示“NameError: name 'PurchaseOrder' is not defined”如果这是一个糟糕的问题,我深表歉意,因为我是 Python 和 Django 的新手。
    • from django.db.models import signals 放在models.py 文件的顶部,而其余代码放在PurchaseOrder 定义的下方。检查我的答案以供参考。
    【解决方案2】:

    收听post_save 信号。

    from django.db.models import signals
    from django.dispatch import receiver
    
    @receiver(signals.post_save, sender=PurchaseOrder)
    def email_handler(sender, **kwargs):
        if kwargs['created']:
            email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
            email.send()
    

    或者在你的模型中定义一个自定义的save 方法。

    class PurchaseOrder(models.Model):
        def save(self, *args, **kwargs):
            # Check if this is a new key
            if not self.pk:
                email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
                email.send()
            super(PurchaseOrder, self).save(*args, **kwargs)
    

    【讨论】:

      【解决方案3】:

      @voithos 是正确的,这是自定义保存是解决问题的好方法。但是,根据对问题的严格回答,从技术上讲,电子邮件是在创建主键之前发送的。这可能无关紧要,但如果确实如此,我会订购如下代码:

      def save(self, *args, **kwargs):
          email = False  # Don't email by default
          # Check if this is a new key
          if not self.pk:
              email = EmailMessage('Purchase Order System', 'your message here', to=['youremail@gmail.com'])
          super(PurchaseOrder, self).save(*args, **kwargs)
          if email:  # Email was created, and we have a new Primary Key, so send now.
              email.send()
      

      注意:如果您需要一种方法来引用新创建的实例(例如,电子邮件需要包含一个包含刚刚创建的主键的链接),我个人会使用 @kroolik 提供的信号方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-06
        • 1970-01-01
        • 2017-03-30
        • 2015-04-19
        • 2019-09-03
        • 2011-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多