使用 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 项目中的一些配置
来源: http://www.bubuko.com/infodetail-3345555.html