使用celery异步发送邮件,页面可以不需等发送邮件成功才加载,celery都工作原理如下图:
邮件发送的过程:
- Django网站先发送到smtp服务器
- smtp服务器再把邮件发送方到目的邮箱
在如上的情况下,假定Django网站发送邮件到smtp耗时是5s,那么用户在表单中输入信息之后提交,页面需要刷新5s才会跳转。显然这样极大影响了用户体验
首先在项目虚拟环境里安装celery模块:
- pipenv install celery
- 如果使用的是win10操作系统运行celery4.x版本可能会有问题,需要安装另外一个模块:pipenv install eventlet
在django项目里新建一个python package,文件名叫celery_tasks,里面创建一个叫tasks.py的python文件
- 首先确保电脑上已经安装Redis数据库,pipenv install redis或者远程的redis是否已启动
- 在tasks.py中的代码如下:其中第8-11行,是在使用不同的电脑运行celery的发起者、中间人、中间人时所需要用到的,这里我都是在一台电脑上运行,所以完全可以不写
# # 在任务一段加这几句代码初始化配置
# import os
# import django
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'dailyfresh.settings')
# django.setup()
#使用celery
from celery import Celery
from django.core.mail import send_mail
from django.conf import settings
import time
import redis
#创建一个Celery的实例对象
broker='redis://127.0.0.1:6379/8'
app = Celery("celery_tasks.tasks",broker=broker)
#定义发送邮件任务函数
@app.task
def send_register_active_email(to_email,username,token):
"""发送激活邮件"""
# 发送邮件
subject = '天天生鲜欢迎信息'
message = ''
sender = settings.EMAIL_FROM
receiver = [to_email]
html_message = '<h1>{0}, 欢迎您成为天天生鲜注册会员</h1>请点击下面链接激活您的账户<br/><a href="http://127.0.0.1:8000/user/active/{1}">http://127.0.0.1/user/active/{2}</a>'.format(
username, token, token)
send_mail(subject, message, sender, receiver, html_message=html_message)
#time.sleep(5)
修改原先视图函数里发送邮件的部分,修改如下:
#发送邮件
# subject = '天天生鲜欢迎您'
# message = ''
# from_email = settings.EMAIL_FROM
# recipient_list = [email]
# html_message = '<h1>{0},欢迎您成为天天生鲜注册会员</h1>请点击下面的链接激活您的账户<br/><a href="http://127.0.0.1:8000/user/active/{1}">http://127.0.0.1:8000/user/active/{2}</a>'.format(username,token,token)
# send_mail(subject,message,from_email,recipient_list,html_message=html_message)
send_register_active_email.delay(email,username,token)
#返回应答,跳转到首页
return redirect(reverse('goods:index'))
现在环境和代码都已经完成了,接下来在终端运行命令:
-
celery -A celery_tasks.tasks worker -l info -P eventlet
-
其中 -P enentlet 是为了防止 win10 运行出错而附加的
-
这样我们就启动了任务处理者
-
如果任务处理者和redis都在另一台计算机上,就需要把项目和环境拷贝过去,然后也是同样的命令启动,不过在不同的计算机上就一定不能少了tasks.py中的8-11行的内容,因为tasks.py文件中的操作用到了Django项目中的一些配置