发送邮件需要使用到SMTP服务器
·
常用的免费SMTP服务器有QQ,163,126
这里以QQ邮箱为例:
1)进入QQ邮箱首页,点击设置
2)点击smtp服务的开启按钮
3)得到授权码
·
Django中进行邮箱配置
settings.py
#发送邮件配置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
#发送邮件的邮箱
EMAIL_HOST_USER = 'xxx@qq.com'
#在邮箱中设置的客户端授权密码
EMAIL_HOST_PASSWORD = 'xxxx'
#收件人看到的发件人
EMAIL_FROM = '名字<xxx@qq.com>'
·
在视图函数中进行操作
from django.core.mail import send_mail
subject = '天天生鲜信息' # 邮件主题
message = '' # 邮件正文,但是无法解析html格式
sender = settings.EMAIL_FROM # 发送人的邮箱
recevier = [email] # 收件人列表
# token为已经加密了的账户id
html_message = '<h1>%s欢迎您成为天天生鲜的注册会员</h1>请点击下面的链接激活您的帐户<br/><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a>' % (username, token, token)
# 必须按照该参数的顺序去写,前四个参数缺一不可,html_message是可加的参数(可解析html格式的邮件正文)
send_mail(subject, message, sender, recevier, html_message=html_message)
实验结果:
·
在开发中,服务器发送邮件,在这段时间中服务器呈现一个阻塞的状态,也就是等到邮件发送完毕后,服务器才会响应浏览器,用户才能继续浏览网页
·
解决方法:
将耗时的任务放到后台异步执行,不影响用户其他操作。例如上传,图形处理等耗时的任务。
我们引入celery
。celery
除了可以异步执行任务外,还可以实现定时处理某些任务。
·
celery
Celery是一个功能完备即插即用的任务队列。
它使得我们不需要考虑复杂的问题,使用非常简单。
celery适用异步处理问题,当发送邮件、或者文件上传,图像处理等等一些比较耗时的操作,我们可将其异步执行,这样用户不需要等待很久,提高用户体验。
特点
● 简单,易于使用和维护,有丰富的文档
● 高效,单个celery进程每分钟可以处理数百万个任务
● 灵活,celery中几乎每个部分都可以自定义扩展
● celery非常易于集成到一些web开发框架中
·
celery的使用模型
任务队列的中间人可以是:
1. RabbitMQ
RabbitMQ是一个功能完备,稳定的并且易于安装的broker,是生产环境中最优的选择。
2. Redis
Redis是一款功能完备的broker可选项,但是存在因意外中断或者电源故障导致导致数据丢失的情况。
·
在python中使用celery
以Django框架中发送邮件为例
1)安装celery
pip install celery
·
2)新建python包(起名celery_task),在包中创建python文件(起名tasks)
·
3)在tasks文件中导入celery包的Celery类,创建一个Celery类的实例对象
# 使用celery
from celery import Celery
# 创建一个Celery类的实例对象
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')
注:Celery类需要两个参数,第一个是 任务发出者所在包,第二个是 任务队列(中间人)的地址信息。此时需要在所选定的中间人电脑中启动redis服务(
sudo service redis start
)
·
4)创建任务函数,并且通过上一步创建的类对象的task方法对该任务函数进行装饰
# 使用celery
from celery import Celery
from django.conf import settings
from django.core.mail import send_mail
# 创建一个Celery类的实例对象
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')
# 定义任务函数
@app.task
def send_register_email(to_email, username, token):
"""发送激活邮件"""
# 组织邮件信息
subject = '天天生鲜信息' # 邮件主题
message = '' # 邮件正文
sender = settings.EMAIL_FROM # 发件人
receiver = [to_email] # 收件人列表
html_message = '<h1>%s欢迎您注册激活天天生鲜会员,请点击下面的链接进行会员激活</h1><br/><a href="http://127.0.0.1/user/active/%s">' \
'http://127.0.0.1/user/active/%s</a>' % (username, token, token)
send_mail(subject, message, sender, receiver, html_message=html_message)
注:这里用
app.task
进行装饰器装饰是为了给任务函数增加delay()
方法,使得可以向任务队列(中间人)发出任务
·
5)在Django视图函数中当需要向任务队列发出任务时,导入任务函数所在包,调用该任务函数的delay()
方法
from celery_task.tasks import send_register_email
# 发邮件
send_register_email.delay(email, username, token)
·
6)在任务处理者的电脑上也需要任务发出者的代码并且安装celery。
·
7)在任务处理者copy的项目中如果需要引用Django初始化后的变量(如settings.py文件中的属性),则必须先在代码中对其进行初始化
celery_task/tasks.py
# 使用celery
from celery import Celery
from django.conf import settings
from django.core.mail import send_mail
# 在任务处理这一端加上,进行Django初始化
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings")
django.setup() # 启动初始化
# 创建一个Celery类的实例对象
app = Celery('celery_task.tasks', broker='redis://192.168.43.85:6379/1')
# 定义任务函数
@app.task
def send_register_email(to_email, username, token):
"""发送激活邮件"""
# 组织邮件信息
subject = '天天生鲜信息' # 邮件主题
message = '' # 邮件正文,但是无法解析html标签
sender = settings.EMAIL_FROM # 发件人
receiver = [to_email] # 收件人列表
html_message = '<h1>%s欢迎您注册激活天天生鲜会员,请点击下面的链接进行会员激活</h1><br/><a href="http://127.0.0.1/user/active/%s">' \
'http://127.0.0.1/user/active/%s</a>' % (username, token, token)
# 必须按照该参数的顺序去写,前四个参数缺一不可,html_message是可加的参数(可解析html格式的邮件正文)
send_mail(subject, message, sender, receiver, html_message=html_message)
注:Django进行初始化的代码在Django项目中的
wsgi.py
文件中
·
8)启动任务处理者,在任务处理者的电脑中进入已经复制好的项目目录中执行命令:
celery -A celery_task.tasks worker -l info
celery进行处理
·
注:当任务发出者的代码改变时,同时也需要改变任务处理者的代码