Нужна помощь в добавлении уведомления по электронной почте в Django

Я пытаюсь реализовать проект временной таблицы. Я использую Django rest-framework и использую Postgres в качестве базы данных. Мой клиент попросил меня вот о чем (Если пользователь уже существует в базе данных или новый пользователь создает свой аккаунт, должно быть отправлено электронное письмо, когда опция post была отправлена в 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)

Добрый день, так как я новичок в Django, помогите мне в добавлении этой функциональности

Это действительно важный вопрос. Я только что проделал подобную работу несколько дней назад. Я добавляю в соответствии с моей работой.

в вашем serializers.py вы можете сделать это.

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
        'noreply@email.com', #from_email
        ['user@email.com'], #to_email
        fail_silently=False,
    )

и вам нужно установить метод отправки электронной почты в 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'

Вы можете использовать celery для асинхронной отправки писем.

но сначала вам следует сделать это для проверки. Вот официальная документация по отправке электронной почты. Это действительно здорово.

и как я упоминал выше о mailtrap, вот ссылка mailtrap

И вы можете следовать этому руководству для настройки электронной почты вот ссылка

Все же, если у вас возникнет какая-либо путаница, дайте мне знать. Большое спасибо.

Решения такие же, как Anny как предложено здесь

Решения были:

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
        'noreply@email.com', #from_email
        ['user@email.com'], #to_email
        fail_silently=False,
    )

Единственная проблема с этим решением заключается в том, что оно увеличит время загрузки. В качестве альтернативы вы можете использовать потоковое управление и перенаправить процесс отправки электронной почты в другой поток

Вы можете сделать это, создав новый файл с именем 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)

и в вашем 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 validate_data
    
    
    class Meta:
        model= User
        fields ='__all__'
       
        password = serializers.CharField(max_length=128, write_only=True, required=True)
    
Вернуться на верх