Django發(fā)送郵件的方法-創(chuàng)新互聯(lián)

創(chuàng)新互聯(lián)www.cdcxhl.cn八線動(dòng)態(tài)BGP香港云服務(wù)器提供商,新人活動(dòng)買(mǎi)多久送多久,劃算不套路!

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、三穗ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的三穗網(wǎng)站制作公司

小編給大家分享一下Django發(fā)送郵件的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!

當(dāng)我們創(chuàng)建一個(gè)網(wǎng)站時(shí),經(jīng)常會(huì)有發(fā)送郵件的需要。無(wú)論是用戶(hù)注冊(cè),還是用戶(hù)忘記密碼,又或者是用戶(hù)下單后進(jìn)行付款確認(rèn),都需要發(fā)

送不同的郵件。所以發(fā)送郵件的需求實(shí)際上是非常重要的,而且如果如果不在一開(kāi)始就建造結(jié)構(gòu)清晰的郵件服務(wù),到后面可能會(huì)是一團(tuán)糟。

基本的郵件發(fā)送

假設(shè)我們希望在用戶(hù)注冊(cè)到我們的網(wǎng)站。我們可以參照Django文檔,向驗(yàn)證通過(guò)并創(chuàng)建成功的用戶(hù)發(fā)送郵件。具體實(shí)現(xiàn)如下:

import logging

from rest_framework.views import APIView
from django.http import JsonResponse
from django.core.mail import send_mail

from users.models import User

logger = logging.getLogger('django')


class RegisterView(APIView):

    def post(self, request):
        # Run validations
        if not request.data:
            return JsonResponse({'errors': 'User data must be provided'}, status=400)
        if User.objects.filter(email=request.data['email']).exists():
            return JsonResponse({'errors': 'Email already in use'}, status=400)
        try:
            # Create new user
            user = User.objects.create_user(email=request.data['email'].lower())
            user.set_password(request.data['password'])
            user.save()
            
            # Send welcome email
            send_mail(
                subject='Welcome!',
                message='Hey there! Welcome to our platform.',
                html_message='<p><strong>Het there!</strong> Welcome to our platform.</p>'
                from_email='from@example.com',
                recipient_list=[user.email],
                fail_silently=False,
            )
            
            return JsonResponse({'status': 'ok'})
        except Exception as e:
            logger.error('Error at %s', 'register view', exc_info=e)
            return JsonResponse({'errors': 'Wrong data provided'}, status=400)

當(dāng)然肯定文檔中所說(shuō)的那樣,你也必須提前設(shè)定好一些重要的配置項(xiàng),例如EMAIL_HOST和EMAIL_PORT。

很好!現(xiàn)在我們已經(jīng)發(fā)送了歡迎郵件!

創(chuàng)建一個(gè)mailer類(lèi)

正如我之前所說(shuō),在我們的應(yīng)用中不同的模塊可能都需要發(fā)送郵件,所以最好有一個(gè)電子郵件服務(wù)或者mailer類(lèi)來(lái)處理所有的郵件請(qǐng)求。更簡(jiǎn)單,因?yàn)槲覀儾辉傩枰看味既シ槿看a。

iimport logging

from django.conf import settings
from django.core.mail import send_mail

from users.models import User

logger = logging.getLogger('django')


class BaseMailer():
    def __init__(self, to_email, subject, message, html_message):
        self.to_email = to_email
        self.subject = subject
        self.message = message
        self.html_message = html_message

    def send_email(self):
        send_mail(
            subject=self.subject,
            message=self.message,
            html_message=self.html_message,
            from_email='from@example.com',
            recipient_list=[self.to_email],
            fail_silently=False,
        )

讓我們來(lái)看看經(jīng)過(guò)這次改變后,注冊(cè)服務(wù)的視圖層是某種子:

import logging

from rest_framework.views import APIView
from django.http import JsonResponse
from django.core.mail import send_mail

from users.models import User
from users.mailers import BasicMailer

logger = logging.getLogger('django')


class RegisterView(APIView):

    def post(self, request):
        # Run validations
        if not request.data:
            return JsonResponse({'errors': 'User data must be provided'}, status=400)
        if User.objects.filter(email=request.data['email']).exists():
            return JsonResponse({'errors': 'Email already in use'}, status=400)
        try:
            # Create new user
            user = User.objects.create_user(email=request.data['email'].lower())
            user.set_password(request.data['password'])
            user.save()
            
            # Send welcome email
            BasicMailer(to_email=user.email, 
                        subject='Welcome!', 
                        message='Hey there! Welcome to our platform.', 
                        html_message='<p><strong>Het there!</strong> Welcome to our platform.</p>').send_email()
            
            return JsonResponse({'status': 'ok'})
        except Exception as e:
            logger.error('Error at %s', 'register view', exc_info=e)
            return JsonResponse({'errors': 'Wrong data provided'}, status=400)

作者:cyril_lee
鏈接:https://juejin.im/post/5eb6171c5188256d7a3cac97
來(lái)源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。

mailer子類(lèi)

現(xiàn)在我們已經(jīng)把所有的“郵件代碼”移動(dòng)到一個(gè)單獨(dú)的地方,可以把它利用起來(lái)啦!這時(shí)候可以繼續(xù)創(chuàng)建特定的mailer類(lèi),并讓它們知道每次被調(diào)用時(shí)該發(fā)送什么內(nèi)容。讓我們創(chuàng)建一個(gè)mailer類(lèi)用來(lái)在每次用戶(hù)注冊(cè)時(shí)進(jìn)行調(diào)用,另一個(gè)mailer類(lèi)用來(lái)發(fā)送訂單的確認(rèn)信息。

import logging

from django.conf import settings
from django.core.mail import send_mail

from users.models import User

logger = logging.getLogger('django')


class BaseMailer():
    def __init__(self, to_email, subject, message, html_message):
        self.to_email = to_email
        self.subject = subject
        self.message = message
        self.html_message = html_message

    def send_email(self):
        send_mail(
            subject=self.subject,
            message=self.message,
            html_message=self.html_message,
            from_email='from@example.com',
            recipient_list=[self.to_email],
            fail_silently=False,
        )
        
        
class RegisterMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email,  
                         subject='Welcome!', 
                         message='Hey there! Welcome to our platform.', 
                         html_message='<p><strong>Het there!</strong> Welcome to our platform.</p>')
        

class NewOrderMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email,  
                         subject='New Order', 
                         message='You have just created a new order', 
                         html_message='<p>You have just created a new order.</p>')

這表明在不同的場(chǎng)景下集成郵件服務(wù)是非常簡(jiǎn)單的。你只需要構(gòu)造一個(gè)基礎(chǔ)的郵件類(lèi)來(lái)進(jìn)行實(shí)現(xiàn),然后在子類(lèi)中設(shè)置具體內(nèi)容。

因?yàn)椴挥脤?shí)現(xiàn)所有郵件相關(guān)的代碼,所以現(xiàn)在我們注冊(cè)服務(wù)的視圖層看起來(lái)更加簡(jiǎn)明:

import logging

from rest_framework.views import APIView
from django.http import JsonResponse
from django.core.mail import send_mail

from users.models import User
from users.mailers import RegisterMailer

logger = logging.getLogger('django')


class RegisterView(APIView):

    def post(self, request):
        # Run validations
        if not request.data:
            return JsonResponse({'errors': 'User data must be provided'}, status=400)
        if User.objects.filter(email=request.data['email']).exists():
            return JsonResponse({'errors': 'Email already in use'}, status=400)
        try:
            # Create new user
            user = User.objects.create_user(email=request.data['email'].lower())
            user.set_password(request.data['password'])
            user.save()
            
            # Send welcome email
            RegisterMailer(to_email=user.email).send_email()
            
            return JsonResponse({'status': 'ok'})
        except Exception as e:
            logger.error('Error at %s', 'register view', exc_info=e)
            return JsonResponse({'errors': 'Wrong data provided'}, status=400)
使用Sendgrid

假設(shè)我們必須使用正式的蟒庫(kù)將我們的郵件服務(wù)后端遷移Sendgrid(一個(gè)用于交易和營(yíng)銷(xiāo)郵件的客戶(hù)通信平臺(tái))。我們將不能再使用的Django的SEND_EMAIL方法,而且我們還不得不使用新庫(kù)的語(yǔ)法。

嗯,但我們還是很幸運(yùn)的地方!因?yàn)槲覀円呀?jīng)將所有與郵件管理相關(guān)的代碼都放到了一個(gè)單獨(dú)的地方,所以我們可以很輕松的進(jìn)行這場(chǎng)比賽

import logging

from django.conf import settings
from sendgrid import SendGridAPIClient, Email, Personalization
from sendgrid.helpers.mail import Mail

from users.models import User

logger = logging.getLogger('django')


class BaseMailer():
    def __init__(self, email, subject, template_id):
        self.mail = Mail()
        self.subject = subject
        self.template_id = template_id

    def create_email(self):
        self.mail.from_email = Email(settings.FROM_EMAIL)
        self.mail.subject = self.subject
        self.mail.template_id = self.template_id
        personalization = Personalization()
        personalization.add_to(Email(self.user.email))
        self.mail.add_personalization(personalization)

    def send_email(self):
        self.create_email()
        try:
            sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
            sg.send(self.mail)
        except Exception as e:
            logger.error('Error at %s', 'mailer', exc_info=e)
            

class RegisterMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email, subject='Welcome!', template_id=1234)

        
class NewOrderMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email, subject='New Order', template_id=5678)

請(qǐng)注意,您必須在配置文件中設(shè)置Sendgrid的api密鑰,以及指定需要被使用的模板的ID,Sendrid會(huì)直接從自己的頁(yè)面中根據(jù)這個(gè)ID來(lái)加載指定的html郵件模版。

太好了!這并不困難,而且我們不用去修改發(fā)送郵件的每一行代碼。

現(xiàn)在讓我們的步子再邁大一點(diǎn)。

根據(jù)域信息定制郵件內(nèi)容

當(dāng)然我們發(fā)送郵件的時(shí)候,有時(shí)候可能也會(huì)使用一些域信息來(lái)填充模板。比如說(shuō),如果在歡迎郵件里面能有新用戶(hù)的名字,那肯定會(huì)顯得更友好。Sendgrid 允許你在郵件模板中定義變量,這些變量將替換為從我們這里接收的實(shí)際信息。所以現(xiàn)在讓我們來(lái)添加這部分?jǐn)?shù)據(jù)吧!

import logging

from django.conf import settings
from sendgrid import SendGridAPIClient, Email, Personalization
from sendgrid.helpers.mail import Mail

from users.models import User

logger = logging.getLogger('django')


class BaseMailer():
    def __init__(self, email, subject, template_id):
        self.mail = Mail()
        self.user = User.objects.get(email=email)
        self.subject = subject
        self.template_id = template_id
        self.substitutions = {
            'user_name': self.user.first_name,
            'user_surname': self.user.last_name
        }


    def create_email(self):
        self.mail.from_email = Email(settings.FROM_EMAIL)
        self.mail.subject = self.subject
        self.mail.template_id = self.template_id
        personalization = Personalization()
        personalization.add_to(Email(self.user.email))
        personalization.dynamic_template_data = self.substitutions
        self.mail.add_personalization(personalization)

    def send_email(self):
        self.create_email()
        try:
            sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
            sg.send(self.mail)
        except Exception as e:
            logger.error('Error at %s', 'mailer', exc_info=e)
            

class RegisterMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email, subject='Welcome!', template_id=1234)

        
class NewOrderMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email, subject='New Order', template_id=5678)

這里我看到的唯一一個(gè)問(wèn)題是替換方案不那么靈活。很可能會(huì)發(fā)生的情況是,我們傳遞的數(shù)據(jù)可能是用戶(hù)根據(jù)請(qǐng)求的上下文訪問(wèn)不到的。比如說(shuō),新的訂單編號(hào)、重置密碼的鏈接等等。這些變量參數(shù)可能很多,把它們作為命名參數(shù)傳遞可能會(huì)讓代碼變得比較臟亂。我們希望的是一個(gè)基于關(guān)鍵字,并且長(zhǎng)度可變的參數(shù)列表,一般來(lái)說(shuō)會(huì)被定義為 **kwargs,但在此我們命名它為 **substitutions,讓這個(gè)表達(dá)會(huì)更形象:

import loggingfrom django.conf import settingsfrom sendgrid import SendGridAPIClient, Email, Personalizationfrom sendgrid.helpers.mail import Mailfrom users.models import User

logger = logging.getLogger('django')class BaseMailer():
    def __init__(self, email, subject, template_id, **substitutions):
        self.mail = Mail()
        self.user = User.objects.get(email=email)
        self.subject = subject
        self.template_id = template_id
        self.substitutions = {            'user_name': self.user.first_name,            'user_surname': self.user.last_name
        }        
        for key in substitutions:
            self.substitutions.update({key: substitutions[key]})    def create_email(self):
        self.mail.from_email = Email(settings.FROM_EMAIL)
        self.mail.subject = self.subject
        self.mail.template_id = self.template_id
        personalization = Personalization()
        personalization.add_to(Email(self.user.email))
        personalization.dynamic_template_data = self.substitutions
        self.mail.add_personalization(personalization)    def send_email(self):
        self.create_email()        try:
            sg = SendGridAPIClient(settings.SENDGRID_API_KEY)
            sg.send(self.mail)        except Exception as e:
            logger.error('Error at %s', 'mailer', exc_info=e)            class RegisterMailer(BaseMailer):
    def __init__(self, to_email, **substitutions):
        super().__init__(to_email, subject='Welcome!', template_id=1234, **substitutions)        class NewOrderMailer(BaseMailer):
    def __init__(self, to_email):
        super().__init__(to_email, subject='New Order', template_id=5678, **substitutions)

如果希望將額外信息傳遞給 mailer 類(lèi),就需要按如下編碼:

NewOrderMailer(user.email, order_id=instance.id).send_email()
PasswordResetMailer(user.email, key=password_token.key).send_email()

網(wǎng)站標(biāo)題:Django發(fā)送郵件的方法-創(chuàng)新互聯(lián)
分享路徑:http://bm7419.com/article4/didjoe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、網(wǎng)站營(yíng)銷(xiāo)服務(wù)器托管、網(wǎng)站設(shè)計(jì)公司商城網(wǎng)站、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)