創(chuàng)新互聯(lián)www.cdcxhl.cn八線動態(tài)BGP香港云服務(wù)器提供商,新人活動買多久送多久,劃算不套路!
小編給大家分享一下Django發(fā)送郵件的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討方法吧!
當(dāng)我們創(chuàng)建一個網(wǎng)站時,經(jīng)常會有發(fā)送郵件的需要。無論是用戶注冊,還是用戶忘記密碼,又或者是用戶下單后進行付款確認,都需要發(fā)
送不同的郵件。所以發(fā)送郵件的需求實際上是非常重要的,而且如果如果不在一開始就建造結(jié)構(gòu)清晰的郵件服務(wù),到后面可能會是一團糟。
基本的郵件發(fā)送假設(shè)我們希望在用戶注冊到我們的網(wǎng)站。我們可以參照Django文檔,向驗證通過并創(chuàng)建成功的用戶發(fā)送郵件。具體實現(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)然肯定文檔中所說的那樣,你也必須提前設(shè)定好一些重要的配置項,例如EMAIL_HOST和EMAIL_PORT。
很好!現(xiàn)在我們已經(jīng)發(fā)送了歡迎郵件!
創(chuàng)建一個mailer類正如我之前所說,在我們的應(yīng)用中不同的模塊可能都需要發(fā)送郵件,所以最好有一個電子郵件服務(wù)或者mailer類來處理所有的郵件請求。更簡單,因為我們不再需要每次都去翻遍全部代碼。
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, )
讓我們來看看經(jīng)過這次改變后,注冊服務(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 來源:掘金 著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
mailer子類
現(xiàn)在我們已經(jīng)把所有的“郵件代碼”移動到一個單獨的地方,可以把它利用起來啦!這時候可以繼續(xù)創(chuàng)建特定的mailer類,并讓它們知道每次被調(diào)用時該發(fā)送什么內(nèi)容。讓我們創(chuàng)建一個mailer類用來在每次用戶注冊時進行調(diào)用,另一個mailer類用來發(fā)送訂單的確認信息。
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>')
這表明在不同的場景下集成郵件服務(wù)是非常簡單的。你只需要構(gòu)造一個基礎(chǔ)的郵件類來進行實現(xiàn),然后在子類中設(shè)置具體內(nèi)容。
因為不用實現(xiàn)所有郵件相關(guān)的代碼,所以現(xiàn)在我們注冊服務(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 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è)我們必須使用正式的蟒庫將我們的郵件服務(wù)后端遷移Sendgrid(一個用于交易和營銷郵件的客戶通信平臺)。我們將不能再使用的Django的SEND_EMAIL方法,而且我們還不得不使用新庫的語法。
嗯,但我們還是很幸運的地方!因為我們已經(jīng)將所有與郵件管理相關(guān)的代碼都放到了一個單獨的地方,所以我們可以很輕松的進行這場比賽
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)
請注意,您必須在配置文件中設(shè)置Sendgrid的api密鑰,以及指定需要被使用的模板的ID,Sendrid會直接從自己的頁面中根據(jù)這個ID來加載指定的html郵件模版。
太好了!這并不困難,而且我們不用去修改發(fā)送郵件的每一行代碼。
現(xiàn)在讓我們的步子再邁大一點。
根據(jù)域信息定制郵件內(nèi)容
當(dāng)然我們發(fā)送郵件的時候,有時候可能也會使用一些域信息來填充模板。比如說,如果在歡迎郵件里面能有新用戶的名字,那肯定會顯得更友好。Sendgrid 允許你在郵件模板中定義變量,這些變量將替換為從我們這里接收的實際信息。所以現(xià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)
這里我看到的唯一一個問題是替換方案不那么靈活。很可能會發(fā)生的情況是,我們傳遞的數(shù)據(jù)可能是用戶根據(jù)請求的上下文訪問不到的。比如說,新的訂單編號、重置密碼的鏈接等等。這些變量參數(shù)可能很多,把它們作為命名參數(shù)傳遞可能會讓代碼變得比較臟亂。我們希望的是一個基于關(guān)鍵字,并且長度可變的參數(shù)列表,一般來說會被定義為 **kwargs,但在此我們命名它為 **substitutions,讓這個表達會更形象:
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 類,就需要按如下編碼:
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://www.chinadenli.net/article4/didjoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、網(wǎng)站營銷、服務(wù)器托管、網(wǎng)站設(shè)計公司、商城網(wǎng)站、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)