Home > other >  adding an email notification in Django
adding an email notification in Django

Time:01-25

I am trying a timesheet project. I am using Django rest-framework and using Postgres as my database. My client requested me this (If a user already existed in the database or a new user is creating their account an email should be triggered when the post option was submitted in rest API).

models.py

from django.http import  HttpResponse, HttpResponseRedirect, response
from django.db import models
from django.db.models.deletion import CASCADE
from django.utils import timezone
from django.dispatch import  receiver
from django.db.models.signals import post_save
from django.conf import settings
from django.core.mail import send_mail
from django.db.models import signals
import datetime

from django.core.mail import EmailMessage 




    

class User(models.Model):
    
    CHOICES= (
    ('manager','Manager'),
      ('hr', 'HR'),
     ('hr manager','HR Manager'),
     ('trainee','Trainee')
)

    firstname = models.CharField(max_length=210)
    lastname = models.CharField(max_length=210)
    dob=models.DateField(max_length=8) 
    email=models.EmailField(max_length=254,default=None) 
    password=models.CharField(max_length=100,default=None)
    joiningDate=models.DateTimeField(max_length=8)
    userrole=models.CharField(max_length=20,choices=CHOICES,null=True)
    

def __str__(self):
    return self.firstname 


class Project(models.Model):
    name = models.CharField(max_length=20)
    description=models.TextField()
    type=models.TextField()
    startDate = models.DateTimeField(max_length=10)
    endDate=models.DateTimeField(max_length=10)
    user=models.ManyToManyField(User)
    
    def __str__(self):
        return self.name

    
class Timesheet(models.Model):
    project=models.ManyToManyField(Project)
    Submitted_by=models.ForeignKey(default=None,related_name="SubmittedBy",to='User',on_delete=models.CASCADE)
    status=models.CharField(max_length=200)
    ApprovedBy=models.ForeignKey(default=None,related_name="ApprovedBy",to='User',on_delete=models.CASCADE)
    Date=models.DateField()
    Hours=models.TimeField(null=True)

    def __str__(self):
        return self.id
    
    
class Client(models.Model):
    clientname=models.CharField(max_length=20)
    comapny=models.CharField(max_length=200)
    location=models.CharField(max_length=200)
    email=models.EmailField(max_length=25,default=None)
    
    
    def __str__(self):
        return self.clientname 

serializers.py

from django.db.models import fields
from rest_framework import serializers
from.models import User,Project,Timesheet,Client    



class UserSerializers(serializers.ModelSerializer):
    
    class Meta:
        model= User
        fields ='__all__'
       
        password = serializers.CharField(max_length=128, write_only=True, required=True)
        
        
class ProjectSerializers(serializers.ModelSerializer):
    
    class Meta:
        model= Project
        fields= '__all__'
        
        

class TimesheetSerializers(serializers.ModelSerializer):
    
    class Meta:
        model= Timesheet
        fields= '__all__'
        
        
class ClientSerializers(serializers.ModelSerializer):
    
    class Meta:
        model=Client
        fields=  '__all__'

viewset.py

from rest_framework import viewsets
from rest_framework import permissions
from.import models
from.import serializers


class UserViewset(viewsets.ModelViewSet):
    permission_classes=(permissions.IsAuthenticated,)
    queryset=models.User.objects.all()
    serializer_class=serializers.UserSerializers
    

class ProjectViewSet(viewsets.ModelViewSet):
    permission_classes=(permissions.IsAuthenticated,)
    queryset=models.Project.objects.all()
    serializer_class=serializers.ProjectSerializers
    
class TimesheetViewset(viewsets.ModelViewSet):
    permission_classes=(permissions.IsAuthenticated,)
    queryset=models.Timesheet.objects.all()
    serializer_class=serializers.TimesheetSerializers
    
class ClientViewSet(viewsets.ModelViewSet):
    permission_classes=(permissions.IsAuthenticated,)
    queryset=models.Client.objects.all()
    serializer_class=serializers.ClientSerializers

router.py

from App.viewsets import ClientViewSet, UserViewset,ProjectViewSet,TimesheetViewset
from rest_framework import routers

router = routers.DefaultRouter()
router.register('User',UserViewset)
router.register('Project',ProjectViewSet)
router.register('Timesheet',TimesheetViewset)
router.register('Client',ClientViewSet)

I am new to Django.

CodePudding user response:

It's really an important question. I just did work like this a few days ago. I am adding according to my work.

in your serializers.py you can do this.

from django.core.mail import send_mail

class TimesheetSerializers(serializers.ModelSerializer):

class Meta:
    model= Timesheet
    fields= '__all__'
def create(self, validated_data):
    timesheet = Timesheet.objects.create(**validated_data)
    send_mail(
        'Timesheet {} has been created'.format(timesheet.pk),
        'A new timesheet has been created . DATA: {}'.format(
        validated_data), #mail_body
        '[email protected]', #from_email
        ['[email protected]'], #to_email
        fail_silently=False,
    )

and you need to set email sending method in settings.py

#settings.py
#for sending testing emails you can use mailtrap.io as well that is almost same as smtp server
#for smtp
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'user'
EMAIL_HOST_PASSWORD = '****'
EMAIL_PORT = 587
EMAIL_USE_TLS = True

#for sending emails to terminal
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

You can use celery for sending emails asynchronously.

but at first, you should do this to check. Here is the official documentation for sending email. it's really great.

and as I mentioned above about mailtrap so here is the link mailtrap

And you can follow this tutorial for setup email here is the link

Still, if you have any kind of confusion let me know. Thanks a lot.

CodePudding user response:

The solutions is same as Anny as suggested here

The solutions was:

from django.core.mail import send_mail

class TimesheetSerializers(serializers.ModelSerializer):

class Meta:
    model= Timesheet
    fields= '__all__'
def create(self, validated_data):
    timesheet = Timesheet.objects.create(**validated_data)
    send_mail(
        'Timesheet {} has been created'.format(timesheet.pk),
        'A new timesheet has been created . DATA: {}'.format(
        validated_data), #mail_body
        '[email protected]', #from_email
        ['[email protected]'], #to_email
        fail_silently=False,
    )

The only issue with that solution is, it will increase the loading time. Alternately you can do is use threading and divert the email sending process to a different thread

You can do it by creating new file named utils.py:

import threading
from django.core import mail

class EmailThread(threading.Thread):
    def __init__(self, subject, plain_message, from_email, to_email, html_message):
        self.subject = subject
        self.plain_message = plain_message
        self.from_email = from_email
        self.to_email = to_email
        self.html_message = html_message
        super(EmailThread, self).__init__()

    def run(self):
        mail_send = mail.send_mail(self.subject, self.plain_message, self.from_email, [self.to_email], html_message=self.html_message)
        print('mail send successfully ', mail_send)

and in your serializer.py:

from .utlis.py import *

class UserSerializers(serializers.ModelSerializer):
    
    def create(self, validate_data):
        subject = <subject_here>
        plan_message = <plain_message_in_string>
        from_email = <from_mail>
        to_email = <email_you_want_to_send_to>
        html_message = <if you want to include any html template for mail>
        EmailThread(subject, plain_message, from_email, to_email, html_message).start()
        return User.objects.create(**validated_data)
    
    
    class Meta:
        model= User
        fields ='__all__'
       
        password = serializers.CharField(max_length=128, write_only=True, required=True)
    

and in your settings.py add the following:

# EMAIL CONFIGURATION
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = '<email_user_here>'
EMAIL_HOST_PASSWORD = '<password_here>'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
  •  Tags:  
  • Related