为什么我的 Django 项目的 send_mail 不能正常工作?

Why my django project's send_mail isn't working properly?

我正在创建一个项目,在该项目中,网站会自动将电子邮件发送给今天最后一次支付账单的会员。为此,我在我的 django 项目的 Entry 模型 class 中创建了一个方法。我已经在 project/settings.py 中完全配置了 smtp 设置。 电子邮件将发送给会员,但问题是每次用户刷新页面时都会发送电子邮件。它一次又一次地发送电子邮件。累死了,请告诉我这个问题的解决方法。

这里是entries/models.py

from django.db import models
from django.contrib.auth import get_user_model
import datetime
import uuid
state_choices = (("Andhra Pradesh","Andhra Pradesh"),("Arunachal Pradesh ","Arunachal Pradesh 
"),("Assam","Assam"),("Bihar","Bihar"),("Chhattisgarh","Chhattisgarh"),("Goa","Goa"),)


from django.core.mail import send_mail

class Entry(models.Model):
   entry_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    user = models.ForeignKey(get_user_model(), on_delete=models.CASCADE, 
           related_name="entries")
    member = models.CharField(max_length=200)
    member_id = models.CharField(max_length=25, unique=True)
    email_address = models.EmailField(max_length=252, null=False, blank=False)
    email_send = models.BooleanField(default=True)
   is_email_sent = models.BooleanField(default=False)
   state = models.CharField(max_length=50, null=False, blank=False , choices=state_choices, 
                           default="Rajasthan")
   k_no = models.CharField(max_length=15, unique=True)
   board_name = models.CharField(max_length=100)
   last_date = models.DateField()
   amount = models.PositiveIntegerField()

   def __str__(self):
       return self.member_id

   def send_email(self):
       email_send = self.email_send
       is_email_sent = self.is_email_sent
       if email_send == True and is_email_sent == False:
          message = ("Hello, ") + str(self.member) + (" your electricity bill's last date is 
                     today of id-") + str(self.member_id) + (' and your k no is "') + 
                     str(self.k_no) + ('". ') + ('Your bill amount is ') + str(self.amount) + 
                     (".") + ('So please go to www.wsvincent.com to pay your bill. ') + ("Your 
                     Distributor is '") + str(self.user.username) + ("'")
          receiver = []
          receiver.append(self.email_address)
          if self.last_date == datetime.date.today():
              send_mail("Smart Alert", message, "officialsmartalert@gmail.com", receiver, 
                        fail_silently=False,) 
        
        return True
        is_email_sent = True

这里是settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'mygmailaccount@gmail.com'
EMAIL_HOST_PASSWORD = "mygmailpassword"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
    

请告诉我这个问题的解决方案是什么。

你现在的代码主要有两个问题:

  • 问题: 你设置is_email_sent = True的那一行在函数return之后,所以永远不会执行。

    解决方法:在函数前设置变量return。实际上,它应该在 send_mail() 执行后立即发生

        def send_email(self):
            ...
            if email_send == True and is_email_sent == False:
                ...
                if self.last_date == datetime.date.today():
                    send_mail(...) 
                    is_email_sent = True
            return True
    
  • 问题: 变量is_email_sent是一个局部变量,所以它只会存在于你的函数范围内,不会持续存在您的用户的请求。

    解决方案:设置模型实例属性并将其save到数据库,这样它就会在您的用户请求之间持续存在。

        def send_email(self):
            ...
            if email_send == True and is_email_sent == False:
                ...
                if self.last_date == datetime.date.today():
                    send_mail(...) 
                    self.is_email_sent = True
                    self.save()
            return True
    

发送电子邮件后,在 self 上设置 is_email_sent 属性,然后保存对象,以便将其持久保存到 DB

def send_email(self):
    ...
    self.is_email_sent = True
    self.save()
    return True