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

Time:03-12

I was creating a project in which the website will automatically send the emails to the member who's last date of bill payment is today. To do so I created a method in the model class of Entry in my django project. I have fully configured the smtp settings in project/settings.py . The email is going to the member but the issue is that each time the user refreshes the page the email is sent. It is sending email again and again. I am tired out of it, please tell me the solution of this problem.

here is 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, "[email protected]", receiver, 
                        fail_silently=False,) 
        
        return True
        is_email_sent = True

here is settings.py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = '[email protected]'
EMAIL_HOST_PASSWORD = "mygmailpassword"
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False
    

please tell me what is the solution of this problem.

CodePudding user response:

There are mainly two problems with your current code:

  • Problem: The line where you set is_email_sent = True lies after the function return, so it'll never be executed.

    Solution: Set the variable before the function return. Actually, it should happen right after send_mail() is executed

        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
    
  • Problem: The variable is_email_sent is a local variable, so it will only exist on your function scope, and wouldn't persist between your user's requests.

    Solution: Set the model instance attribute and save it to database, so it will persist between your user's requests.

        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
    

CodePudding user response:

After you send the email set the is_email_sent attribute on self and then save the object so that it is persisted to the DB

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