Нужна помощь в добавлении уведомления по электронной почте в 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)