celery异步发邮件
安装celery
安装包
pip3 install Django==2.2
pip3 install celery==4.4.7
pip3 install redis==3.5.3
1.在项目settings.py中配置
# 配置邮件发送 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' # 如果为163邮箱,设置为smtp.163.com EMAIL_PORT = 25 # 或者 465/587是设置了 SSL 加密方式 # 发送邮件的邮箱 EMAIL_HOST_USER = '2962228990@qq.com' # 在邮箱中设置的客户端授权密码 EMAIL_HOST_PASSWORD = 'bconlieuwbfoddae' # 第三方登陆使用的授权密码 EMAIL_USE_TLS = True # 这里必须是 True,否则发送不成功 # 收件人看到的发件人, 必须是一直且有效的 EMAIL_FROM = 'youxiaoke<2962228990@qq.com>' DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
2.新建一个celery.py文件
# celery.py文件 import os from celery import Celery # 把celery和django进行组合,识别和加载django的配置文件 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'workorder.settings') # 创建celery实例 app = Celery('workorder') # 指定celery消息队列的配置 app.config_from_object('workorder.config', namespace='CELERY') # 从所有的django-app中加载任务 app.autodiscover_tasks() @app.task(bind=True) def debug_task(self): print('Request: {0!r}'.format(self.request))
3.在__init__.py文件中
# 绝对引用,使我们的celery模块不会与原始的celery冲突 from __future__ import absolute_import, unicode_literals # 加入绝对引入以后,导入当前模块下的内容方法: from xx import xx as xx from .celery import app as celery_app __all__ = ('celery_app',)
4.在config.py中配置
# 消息中间人设置 broker_url = 'redis://127.0.0.1:6379/15' # 结果存储设置 result_backend = 'redis://127.0.0.1:6379/14'
5.在相对应的app应用下创建tasks.py文件
# 绝对引用,使我们的celery模块不会与原始的celery冲突 from __future__ import absolute_import, unicode_literals # 导入原始的celery模块中shared_task from xx import xx from celery import shared_task # 使用django内置函数发送邮件 from django.core.mail import send_mail # 导入django的settings from django.conf import settings from workorder.celery import app @app.task def send_mail_task(username, email, user_id): """ 使用django内置函数发送邮件 """ subject = '工单系统找回密码' # 主题 message = '' # 文本消息 from_email = settings.EMAIL_FROM recipient_list = [email] html_message = '<h3>您好{},欢迎来到工单系统找回密码!请点击以下链接进行激活:</br>< a href="http://127.0.0.1:8080/Update">点击修改密码</ a></h3>'.format( username, user_id) send_mail( subject=subject, message=message, from_email=from_email, recipient_list=recipient_list, html_message=html_message ) # celery -A workorder worker -l info -P eventlet
6.在views.py里面写发送邮箱的接口
class Forgot_Password_View(APIView): """ 发送邮箱 """ def post(self, request): username = request.data.get('username') email = request.data.get('email') print(username, email) if not all([username, email]): return Response({"msg": "参数不完整", "code": 400}) user_obj = User.objects.filter(username=username).first() print(user_obj) if user_obj: send_mail_task.delay(username, email, user_obj.id) return Response({"msg": "邮箱发送成功", "code": 200}) else: return Response({'msg': "err"})
发送邮箱前端
<template> <a-form :form="form"> 用户名:<input type="text" v-model="username"> <br> <br> 邮箱:<input type="text" v-model="email"> <!-- <a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="用户名" > <a-input v-model="username" v-decorator="[ 'username', { rules: [{ required: true, message: 'Please input your name' }] }, ]" placeholder="Please input your name" /> </a-form-item> --> <!-- <a-form-item :label-col="formItemLayout.labelCol" :wrapper-col="formItemLayout.wrapperCol" label="邮箱" > <a-input v-model="email" v-decorator="[ 'nickname', { rules: [{ required: checkNick, message: 'Please input your nickname' }] }, ]" placeholder="Please input your nickname" /> </a-form-item> --> <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol"> <!-- <a-checkbox :checked="checkNick" @change="handleChange"> Nickname is required </a-checkbox> --> </a-form-item> <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol"> <a-button type="primary" @click="check"> 发送邮箱 </a-button> </a-form-item> </a-form> </template> <script> const formItemLayout = { labelCol: { span: 8 }, wrapperCol: { span: 8 }, }; const formTailLayout = { labelCol: { span: 8 }, wrapperCol: { span: 15, offset: 4 }, }; import axios from 'axios' export default { data() { return { username:'', email:'', checkNick: false, formItemLayout, formTailLayout, form: this.$form.createForm(this, { name: 'dynamic_rule' }), }; }, methods: { check() { let data={ 'username':this.username, 'email':this.email } axios.post('http://127.0.0.1:8000/user/email/',{'username':this.username,'email':this.email}).then(res=>{ if(res.data.code==200){ console.log(res.data) alert(res.data.msg) this.$router.push('/Update') } }) // this.form.validateFields(err => { // if (!err) { // console.info('success'); // } // }); }, handleChange(e) { this.checkNick = e.target.checked; this.$nextTick(() => { this.form.validateFields(['nickname'], { force: true }); }); }, }, }; </script>
8.点击忘记密码之后修改密码
class UpdatePwd(APIView): def put(self,request): uid=request.data.get('uid') password=request.data.get('password') print(uid,password) userobj=User.objects.filter(id=uid).update( password=make_password(password) ) return Response({'code':200,'msg':'修改成功'})
修改密码前端
<template> <div> 请输入新密码:<input type="text" v-model="password"> <br> <br> <a-form-item :label-col="formTailLayout.labelCol" :wrapper-col="formTailLayout.wrapperCol"> <a-button type="primary" @click="update"> 修改密码 </a-button> </a-form-item> </div> </template> <script> const formTailLayout = { labelCol: { span: 8 }, wrapperCol: { span: 15, offset: 4 }, }; import axios from 'axios' export default { data() { return { password:'', uid:localStorage.getItem('uid'), formTailLayout, } }, methods: { update(){ axios.put('http://127.0.0.1:8000/user/update/',{'password':this.password,'uid':this.uid}).then(res=>{ if(res.data.code==200){ console.log(res.data) alert(res.data.msg) this.$router.push('/login') } }) } }, handleChange(e) { this.checkNick = e.target.checked; this.$nextTick(() => { this.form.validateFields(['nickname'], { force: true }); }); }, created() { } } </script> <style scoped> </style>