使用Django+Celery+Redis實(shí)現(xiàn)異步發(fā)送郵件

使用django+celery+redis實(shí)現(xiàn)異步發(fā)送郵件

一褥实、首先在django項目的settings添加一下的內(nèi)容:

# settings.py
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# 這里我用的是163郵箱
EMAIL_HOST = 'smtp.163.com'  
EMAIL_PORT = 25
# 如果是在阿里云上運(yùn)行的服務(wù)器需要將端口改為465,并設(shè)置EMAIL_USE_SSL = True
EMAIL_USE_SSL = True
EMAIL_PORT = 465
# 發(fā)送郵件的郵箱
EMAIL_HOST_USER = 'xxxxxxxx@126.com'
# 在郵箱中設(shè)置的客戶端授權(quán)密碼
EMAIL_HOST_PASSWORD = 'xxxxxxxx'
# 收件人看到的發(fā)件人
EMAIL_FROM = 'xxxxxxxx<xxxxxxxx@126.com>'

在注冊頁的視圖函數(shù)里寫發(fā)郵件的代碼损离。

# users/views.py
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import SignatureExpired

itsdangerous是一個產(chǎn)生token的庫,由flask的作者編寫僻澎。


為register_handle函數(shù)增加以下代碼,增加了發(fā)送郵件的功能怎棱。此時發(fā)送郵件功能是同步的!

def register_handle(request):
    ......
    # 生成激活的token itsdangerous
    serializer = Serializer(settings.SECRET_KEY, 3600)
    token = serializer.dumps({'confirm':passport.id}) # 返回bytes
    token = token.decode()

    # 給用戶的郵箱發(fā)激活郵件
    send_mail('xxxxxx用戶激活', '', settings.EMAIL_FROM, [email], html_message='<a  % token)

    # 注冊完拳恋,還是返回注冊頁凡资。
    return redirect(reverse('books:index'))

二谬运、使用消息隊列celery來異步發(fā)送郵件。

首先配置celery梆暖。在項目根目錄下創(chuàng)建celery.py文件。

broker是一個消息傳輸?shù)闹虚g件轰驳。每當(dāng)應(yīng)用程序調(diào)用celery的異步任務(wù)的時候,會向broker傳遞消息级解,而后celery的worker將會取到消息冒黑,進(jìn)行對于的程序執(zhí)行,這個中間件可以看做是一個消息隊列勤哗。

那么什么又是backend,通常程序發(fā)送的消息芒划,發(fā)完就完了欧穴,可能都不知道對方時候接受了。為此涮帘,celery實(shí)現(xiàn)了一個backend,用于存儲這些消息以及celery執(zhí)行的一些消息和結(jié)果笑诅。對于 broker,官方推薦是rabbitmq和redis苟鸯,至于backend,就是數(shù)據(jù)庫啦早处。為了簡單起見湾蔓,我們都用redis砌梆。

# bookstore/celery.py
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery

# set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'bookstore.settings')

broker = 'redis://127.0.0.1:6379/6'  # 將要進(jìn)行的任務(wù)
backend = 'redis://127.0.0.1:6379/7' # 返回的結(jié)果
app = Celery('bookstore', broker=broker, backend=backend)


# Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
#   should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY')

# Load task modules from all registered Django app configs.
app.autodiscover_tasks()


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

然后在將要使用celery的app目錄下中編寫異步任務(wù)——創(chuàng)建tasks.py文件。

# users/tasks.py
from __future__ import absolute_import, unicode_literals
from celery import shared_task
from django.conf import settings
from django.core.mail import send_mail

@shared_task
def send_active_email(token, username, email):
    '''發(fā)送激活郵件'''
    subject = 'XXXXXXXXXXXXX' # 標(biāo)題
    message = 'XXXXXXXXXXXXX'
    sender = settings.EMAIL_FROM # 發(fā)件人
    receiver = [email] # 收件人列表
    html_message = '<a %token
    send_mail(subject, message, sender, receiver, html_message=html_message)

然后在視圖函數(shù)中導(dǎo)入異步任務(wù)桃序。

from users.tasks import send_active_email
def register_handle(request):
    ...
    send_active_email.delay(token, username, email)
    ...

然后改寫根應(yīng)用文件夾里的init.py,將整個文件改為:

from __future__ import absolute_import, unicode_literals

from .celery import app as celery_app

__all__ = ['celery_app']

然后運(yùn)行:(在根目錄媒熊,和manage.py同級)
測試一下是不是能夠正常發(fā)送郵件

$ celery -A bookstore worker -l info

到這就基本上完成了,再加上我上一篇文章所寫的使用supervisor后臺啟動celery就可以了坟比。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市葛账,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌籍琳,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件趋急,死亡現(xiàn)場離奇詭異,居然都是意外死亡宣谈,警方通過查閱死者的電腦和手機(jī)愈犹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進(jìn)店門闻丑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漩怎,“玉大人嗦嗡,你說我怎么就攤上這事〗募溃” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵矮冬,是天一觀的道長。 經(jīng)常有香客問我胎署,道長吆录,這世上最難降的妖魔是什么琼牧? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮巨坊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘趾撵。我一直安慰自己侄柔,他們只是感情好占调,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著妈候,像睡著了一般。 火紅的嫁衣襯著肌膚如雪苦银。 梳的紋絲不亂的頭發(fā)上啸胧,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天纺念,我揣著相機(jī)與錄音,去河邊找鬼想括。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烟逊。 我是一名探鬼主播,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼宪躯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了访雪?” 一聲冷哼從身側(cè)響起详瑞,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤臣缀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后精置,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡氯窍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了狼讨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贝淤。...
    茶點(diǎn)故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡播聪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出布隔,到底是詐尸還是另有隱情,我是刑警寧澤衅檀,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布招刨,位于F島的核電站哀军,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杉适。R本人自食惡果不足惜谎倔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一猿推、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦藕咏、人聲如沸状知。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卦碾。三九已至,卻和暖如春起宽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坯沪。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工绿映, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腐晾,地道東北人。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓藻糖,卻偏偏與公主長得像,于是被迫代替她去往敵國和親巨柒。 傳聞我的和親對象是個殘疾皇子樱拴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評論 2 350

推薦閱讀更多精彩內(nèi)容