【问题标题】:adding an email notification in Django在 Django 中添加电子邮件通知
【发布时间】:2022-01-25 18:39:35
【问题描述】:

我正在尝试一个时间表项目。我正在使用 Django 休息框架并使用 Postgres 作为我的数据库。我的客户要求我这样做(如果用户已经存在于数据库中或新用户正在创建他们的帐户,则在 rest API 中提交 post 选项时应触发电子邮件)。

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 新手。

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    这确实是一个重要的问题。几天前我刚做了这样的工作。 我正在根据我的工作添加。

    在您的 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 异步发送电子邮件。

    但首先,您应该这样做来检查。 Here is the official documentation 用于发送电子邮件。 真的很棒。

    正如我上面提到的关于邮件陷阱,这里是链接mailtrap

    您可以按照本教程设置电子邮件here is the link

    不过,如果您有任何困惑,请告诉我。 非常感谢。

    【讨论】:

    • 解决方案是正确的,我在最近的项目中确实使用过类似的东西
    • 谢谢,我也会听从你的建议。谢谢
    • @Polymath 有什么方法可以附加一个 excel 文档并发送它。
    • @ZoroD 是的,你可以
    • 你能帮帮我吗...@Anny
    【解决方案2】:

    解决方案与Anny 建议的here 相同

    解决方案是:

    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 User.objects.create(**validated_data)
        
        
        class Meta:
            model= User
            fields ='__all__'
           
            password = serializers.CharField(max_length=128, write_only=True, required=True)
        
    

    并在您的 settings.py 中添加以下内容:

    # 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
    

    【讨论】:

    • 嗨@Polymath 感谢您的建议。实际上,我有一个疑问,实际上用户可能是他们将拥有不同电子邮件 ID 的任何人。 to_email = &lt;email_you_want_to_send_to&gt; 在这一行中,我们无法知道给特定用户。邮寄吧! .那么随机人将如何收到邮件,我的人力资源必须有用户登录的通知,我最后的疑问是我需要在 settings.py 中更改哪些内容
    • 您好 Zoro,我已经编辑了帖子以解决您的 settings.py 问题,您能否重复您的疑问,以便在给出任何解决方案之前我能更好地理解
    • Hii @Polymath 代码运行良好,谢谢,但我遇到了to_email = &lt;email_you_want_to_send_to&gt; 的问题,我们需要发送电子邮件,对吗?我尝试提供一个示例电子邮件,它工作得很好......但是用户可能未知并且会有不同的电子邮件所以在这里我如何在不知道用户电子邮件ID的情况下发送邮件。
    • 感谢兄弟@Polymath 代码运行良好,数据库连接成功
    • 非常感谢。我后来用芹菜发送电子邮件。我一定会在我的代码中添加您的建议。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2017-02-08
    • 1970-01-01
    相关资源
    最近更新 更多