zoukankan      html  css  js  c++  java
  • django中使用celery异步发送邮件

    申请163网易发送邮件权限



    在django中settings配置文件

    #配置邮件服务器
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 指定邮件后端
    EMAIL_HOST = 'smtp.163.com' # 发邮件主机
    EMAIL_PORT = 25 # 发邮件端口
    EMAIL_HOST_USER = '填你自己的邮箱' # 授权的邮箱
    EMAIL_HOST_PASSWORD = '授权时候获得的那个密码' # 邮箱授权时获得的密码,非注册登录密码
    EMAIL_FROM = '随便填一点<填你的邮箱>' # 发件人抬头
    EMAIL_USE_TLS = False # 是否使用安全协议传输
    

    创建celery异步任务

    • 在celery_tasks/main.py主入口
    #Celery的入口
    from celery import Celery
    
    # 把celery和django进行组合,必须让celery能识别和加载django的配置文件以及django的类库
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'meiduo.settings.dev')
    
    # 对django框架执行初始化
    import django
    django.setup()
    
    #创建Celery实例  生产者
    celery_app = Celery('meiduo')
    
    #加载配置
    celery_app.config_from_object('celery_tasks.config')
    
    # 注册任务
    celery_app.autodiscover_tasks(['celery_tasks.email'])  #有多个任务可写多个
    
    
    • 在celery_tasks/config.py配置文件中
    # Celery配置文件
    # 指定中间人、消息队列、任务队列、容器,使用redis
    broker_url = "redis://192.168.204.128/10"
    # 结果队列的链接地址
    celery_result_backend = 'redis://127.0.0.1:6379/14'
    
    • 在celery_tasks/email/tasks.py
    from django.core.mail import send_mail
    from django.conf import settings
    from celery_tasks.main import celery_app
    
    @celery_app.task(name='send_verify_email', base=Mytask) #name 起别名  #base的值为监听的那个类
    def send_verify_email(to_email,verify_url):
        """定义发送邮件的任务"""
        # send_mail('标题','普通邮件的正文','发件人','收件人列表','富文本邮件正文')
        subject = '填主题'
        #message = '普通文本'
        #html_message是发送带html样式信息
        html_message = '<p>尊敬的用户您好!</p>' 
                       '<p>感谢您使用xxxx。</p>' 
                       '<p>您的邮箱为:%s 。请点击此链接激活您的邮箱:</p>' 
                       '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)
        send_mail(subject,'',settings.EMAIL_FROM,[to_email],html_message=html_message)
    

    celery异步执行任务不全都是成功的,所以我们需要监听任务

    • 在celery_tasks/email/tasks.py 加上下面的代码
    from celery.task import Task
    # 监听整个任务的钩子
    class Mytask(Task):
        def on_success(self, retval, task_id, args, kwargs):
            print('task success 11111')
            return super(Mytask, self).on_success(retval, task_id, args, kwargs)
    
        def on_failure(self, exc, task_id, args, kwargs, einfo):
            print('task failed')
            # 可以记录到程序中或者任务队列中,让celery尝试重新执行
            return super(Mytask, self).on_failure(exc, task_id, args, kwargs, einfo)
    
        def after_return(self, status, retval, task_id, args, kwargs, einfo):
            print('this is after return')
            return super(Mytask, self).after_return(status, retval, task_id, args, kwargs, einfo)
    
        def on_retry(self, exc, task_id, args, kwargs, einfo):
            print('this is retry')
            return super(Mytask,self).on_retry(exc, task_id, args, kwargs, einfo)
    
    
    • 在django视图views文件中调用
    #创建日志输出器
    logger = logging.getLogger('django')
    
    class EmailView(LoginRequiredJSONMixin,View):
        """添加邮箱"""
        def put(self,request):
            #接收参数
            json_str = request.body.decode()
            json_dict = json.loads(json_str)
            email = json_dict.get('email')
            #校验参数
            if not email:
                return HttpResponseForbidden('缺少email参数')
            if not re.match(r'^[a-z0-9][w.-]*@[a-z0-9-]+(.[a-z]{2,5}){1,2}$', email):
                return HttpResponseForbidden('参数email有误')
            # 将用户传入的邮箱保存到用户数据库的email字段中
            try:
                request.user.email = email
                request.user.save()
            except Exception as e:
                logger.error(e)
                return JsonResponse({'code':RETCODE.DBERR,'errmsg':'添加邮箱失败'})
    
            #发送邮箱验证邮件   这里是调用邮件的
            verify_url = 'www.baidu.com'
            send_verify_email.delay(email,verify_url) #一定要加delay!!!!
    
            return JsonResponse({'code':RETCODE.OK,'errmsg':'OK'})
    
    • 启动
          终端输入命令启动celery:celery -A celery_tasks.main worker -l info -P eventlet
    
    • 发送邮件
          网页中点击你发送邮件的那个按钮,测试,看后台输出
    
    • 遇到的问题
          1.仔细看send_mail(subject,'',settings.EMAIL_FROM,[to_email],html_message=html_message)这边的传参位置,原码中send_mail接收的参数html_message在最后一个,如果你这边调用的时候,不是关键字传参的话,发送出去的短信对方接收到将不会展现文本内容!
          2.启动celery后可能会报错,这边可以看我博客另外一篇讲celery启动后发送邮件报错的解决办法。目前照上面我的代码调用的话,是可以正常成功的接发收邮件的。
          3.视图中调用邮件函数的时候,一定记得要加delay!一定!一定!一定!
    

    -------------------------------------------

    个性签名:代码过万,键盘敲烂!!!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    PHP实现用户在线状态检测
    php面试题汇集2
    php 调用银联接口 【转载】
    【基础算法】基础算法【转载】
    下ue节点
    Python 字典 列表 嵌套 复杂排序大全
    Linux IO 监控与深入分析
    ELK之kibana的web报错[request] Data too large, data for [<agg [2]>] would be larger than limit of
    Elasticsearch聚合优化 | 聚合速度提升5倍
    elasticsearch bulk批量导入 大文件拆分
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/13583561.html
Copyright © 2011-2022 走看看