前记
在验证用户邮箱时,需要发送一个链接给用户的邮箱,让用户点击以确保用户输入的邮箱是他本人所有。
但是email是由提供商进行发送的,我们需要先把请求发给提供商再由提供商发送,如果不使用异步发送,在用户点击按钮后,必须等到后台收到提供商的返回结果,我们才能把数据返回给用户。
1.Celery介绍
由于使用同步发送带来了许多麻烦,所以可以考虑用任务队列进行异步发送,在python中的Celery库发挥的就是这个作用,而且Celery接口简单,开发容易,5分钟就写出了一个异步发送邮件的服务。Celery本身不含消息服务,它使用第三方消息服务来传递任务,目前,Celery支持的消息服务有RabbitMQ、Redis甚至是数据库。
更多介绍以及入门
2.与django结合异步发送邮件的服务
假设之前已经完成了email发送逻辑(同步方式)
2.1setting.py设置
1 2 3 4 5 6 7 8 9 10 11
| EMAIL_HOST = 'smtp.163.com' EMAIL_PORT = 25 EMAIL_HOST_USER = "***" EMAIL_HOST_PASSWORD = "***" EMAIL_USE_TLS = False EMAIL_FROM = "***"
BROKER_URL = 'redis://127.0.0.1:6379/0' BROKER_TRANSPORT = 'redis'
|
2.2celery文件
在自己的project文件夹内(与setting.py同级)
创建celery.py文件,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import os import django
from celery import Celery from django.conf import settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'django_project.settings') django.setup()
app = Celery('django_project')
app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
2.3发送邮件的py
主要是从celery文件导入app并在自己发送的函数上面使用@app.task装饰器
其他的全是我自己的发送邮件规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| from random import Random
from django.core.mail import send_mail from django_project.settings import EMAIL_FROM
from users.models import EmailVerifyRecord from django_project.celery import app
@app.task def send_register_email(email, send_type="register", num=16): """ 发送注册邮件时的链接 :param email: email :param send_type: 'register'or'forget' :return: """ email_record = EmailVerifyRecord() code_str = random_str(num) email_record.code = code_str email_record.email = email email_record.send_type = send_type email_record.save()
if send_type == 'register': email_title = "注册激活链接" email_body = "请点击下面的链接激活你的账号:http://127.0.0.1:8000/active/{0}".format(code_str)
send_mail(email_title, email_body, EMAIL_FROM, [email])
elif send_type == 'forget': email_title = "重置密码链接" email_body = "请点击下面的链接重置你的密码:http://127.0.0.1:8000/reset/{0}".format(code_str)
send_mail(email_title, email_body, EMAIL_FROM, [email])
elif send_type == 'update_email': email_title = "邮箱修改验证码" email_body = "验证码为:{0}".format(code_str)
send_mail(email_title, email_body, EMAIL_FROM, [email])
else: pass
def random_str(random_length=8): """ 随机字符串生成 :param random_length: 生成字符串长度(init) :return: 返回字符串(str) """ code_str = '' generate_random_str = [chr(i) for i in range(65, 91)] + \ [chr(i) for i in range(97, 123)] + \ [str(i) for i in range(10)] chars = ''.join(generate_random_str) length = len(chars) - 1 random = Random() for i in range(random_length): code_str += chars[random.randint(0, length)] return code_str
|
2.4view
将原本发送邮件的函数
1
| send_register_email(email, "update_email", num=4)
|
改为
1
| send_register_email.delay(email, "update_email", num=4)
|
2.5运行celery服务
Broker设置为redis所以必须先启动
检查是否启动并监听端口
在celery所在目录输入命令启动celery
1
| celery -A (自己定义的名字) worker -l debug
|
2.6测试
发送时celery服务的提示,显示succeeded
image