T O P
Image

Django

Django使用celery发送邮件

windows下利用django框架结合celery实现异步发送邮件功能,celery4.X以后的版本不再支持windows

  • By - C灵C

  • 2019年5月27日 12:27


回家更新。


数据库采用 Redis 和 MySQL,提前建好表、配置路由、获取邮箱的授权码。


项目结构图如下所示:

celery.png


settings.py中邮件配置如下:

    # Django认证系统使用的模型类

    AUTH_USER_MODEL = 'user.User'

    # 发送邮件配置

    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

    # SMTP服务地址,使用其他服务器需更换

    EMAIL_HOST = 'smtp.163.com'

    EMAIL_PORT = 25

    # 发送邮件的邮箱,换成自己的

    EMAIL_HOST_USER = '17777788446@163.com'

    # 在邮箱中设置的客户端授权密码,换成自己的

    EMAIL_HOST_PASSWORD = 'cocpy.com'

    # 收件人看到的发件人,<>中地址必须与上方保持一致

    EMAIL_FROM = 'c0c<17777788446@163.com>'


最外层路由配置:

from django.contrib import admin

from django.urls import path, include

urlpatterns = [

    path('admin/', admin.site.urls),

    path('mail/', include(('apps.mail.urls', 'apps.mail'), namespace='mail')), # 邮件验证模块

  ]


配置mail模块下的路由,即mail下的urls.py,具体代码如下:

from django.urls import path, re_path

from apps.mail.views import VerifyMail, UserActivate

urlpatterns = [

    path('verify/', VerifyMail.as_view(), name='verify'),  # 邮件验证

    re_path(r'^activate/(?P<token>.*)$', UserActivate.as_view(), name='activate'), # 用户激活

  ]


views.py中处理请求,安装 pip install itsdangerous进行加密,具体代码如下。

from itsdangerous import TimedJSONWebSignatureSerializer as TJSS

from itsdangerous import SignatureExpired

from django.shortcuts import render, HttpResponse, redirect, reverse

from django.views.generic import View

from django.conf import settings

from apps.mail.models import User

from celery_execute_task.sendmail import send_activate_email

  # Create your views here.

class VerifyMail(View):

    """邮件验证功能"""

    def get(self, request):

        """页面显示"""

        return render(request, 'register.html')

    def post(self, request):

        """业务处理"""

        # 接收数据

        username = request.POST.get('user_name')

        password = request.POST.get('pwd')

        phone = request.POST.get('phone')

        email = request.POST.get('email')

        # 校验数据

        if not all([username, password, phone, email]):

            # 缺少相关数据

            return HttpResponse('校验数据失败')

        user = User.objects.create_user(username, email, password, phone=phone)

        # 正式处理发送邮件

        # 加密用户的身份信息,生成激活token

        serializer = TJSS(settings.SECRET_KEY, 900)

        info = {'confirm': user.id}

        token = serializer.dumps(info)

        # 默认解码为utf8

        token = token.decode()

        # 使用celery发邮件

        send_activate_email.delay(email, username, token)

        return HttpResponse('注册成功,请注意查收激活账户邮件')


class UserActivate(View):

    """用户通过邮件激活功能"""

    def get(self, request, token):

        """点击邮件链接激活业务处理"""

        serializer = TJSS(settings.SECRET_KEY, 900)

        try:

            info = serializer.loads(token)

            # 获取要激活用户的id

            user_id = info['confirm']

            # 根据id获取用户信息

            user = User.objects.get(id=user_id)

            user.is_active = 1

            user.save()

            # 跳转到登录页面

            return HttpResponse('用户已成功激活!')

        except SignatureExpired as se:

            # 激活链接已过期,应重发激活邮件

            return HttpResponse('激活链接已过期!')

 

重点 is coming



通过pip install celery安装celery,

    如果是windows系统由于celery4.X版本不再支持windows,

    所以还需安装eventlet即pip install enentlet。


在项目根目录下新建一个Python package,即结构图中的celery_execute_task 

并在该包下新建sendmail.py文件用来执行异步任务,

具体代码如下:

    import time

    from django.core.mail import send_mail

    from django.conf import settings

    from celery import Celery

    

     # 初始化django环境

    import django

    import os

    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djangoweb.settings')

    django.setup()

    

    # 创建实例对象

     # 第一个parameter:可随意命名,但一般为本文件所在路径

    # broker:指定中间人,斜杠后指定第几个数据库

    app = Celery('celery_execute_task.sendmail', broker='redis://localhost:6379/3')

    

    # 定义任务函数

    @app.task

    def send_activate_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:8000/mail/activate/%s">http://127.0.0.1:8000/mail/activate/%s</a>' % (username, token, token)

    

    send_mail(subject, message, sender, receiver, html_message=html_message)

    time.sleep(5)

 

在MySQL和Redis启动的前提下,启动项目,通过命令启动celery即celery -A celery_execute_task.sendmail worker --loglevel=info -P eventlet,出现如下图所示即为启动成功。

celerysuccess.png


访问前端页面,发送请求,查看邮件。