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
settings.py

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))
celery.py
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
tasks.py

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>

 

 

 

posted @ 2021-01-15 09:29  Aurora.🌻  阅读(125)  评论(1编辑  收藏  举报