zoukankan      html  css  js  c++  java
  • celery使用发送邮件激活

    Celery是一个功能完备即插即用的任务队列。它使得我们不需要考虑复杂的问题,使用非常简单。celery看起来似乎很庞大,本章节我们先对其进行简单的了解,然后再去学习其他一些高级特性。 celery适用异步处理问题,当发送邮件、或者文件上传, 图像处理等等一些比较耗时的操作,我们可将其异步执行,这样用户不需要等待很久,提高用户体验。 celery的特点是:

    • 简单,易于使用和维护,有丰富的文档。
    • 高效,单个celery进程每分钟可以处理数百万个任务。
    • 灵活,celery中几乎每个部分都可以自定义扩展

     任务队列是一种跨线程、跨机器工作的一种机制.

      任务队列中包含称作任务的工作单元。有专门的工作进程持续不断的监视任务队列,并从中获得新的任务并处理.

      celery通过消息进行通信,通常使用一个叫Broker(中间人)来协client(任务的发出者客户端)和worker(任务的处理者). clients发出消息到队列中,broker将队列中的信息派发给worker来处理。

      一个celery系统可以包含很多的worker和broker,可增强横向扩展性和高可用性能。

           Broker(中间人):RabbitMQ和Redis

    models.py

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    
    class User(AbstractUser):
        '''用户模型类'''
    
        class Meta:
            db_table = 'fm_user'
            verbose_name = '用户'
            verbose_name_plural = verbose_name

    setting.py

    #认证模型类
    AUTH_USER_MODEL = "app01.User"
    
    
    #发送邮件配置
    EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
    EMAIL_HOST = 'smtp.qq.com'
    EMAIL_PORT = 25
    #发送邮件的邮箱
    EMAIL_HOST_USER = 'chvv1016@qq.com'
    #在邮箱中设置的客户端授权密码
    EMAIL_HOST_PASSWORD = 'xxxxxxxxx'
    #收件人看到的发件人
    EMAIL_FROM = '天猫商城<chvv1016@qq.com>'

    创建一个celery_tasks的python包文件,然后创建一个tasks.py文件

    from celery import Celery
    from django.conf import settings
    from django.core.mail import send_mail
    import time
    
    #django环境初始化
    #下面四句加到任务处理者一段,即ubuntu里面的任务处理者,ubuntu作为处理者,要把全部代码复制过去
    #ubuntu中启动命令 celery -A celery_tasks.tasks worker -l info
    import os
    import django
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "celery_demo.settings")
    django.setup()
    
    # 创建一个celery的实例对象
    app = Celery("celery_tasks.tasks",broker='redis://:chenchen@192.168.170.141:6379/8')
    
    #定义任务函数
    @app.task
    def send_register_active_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/active/%s'>http://127.0.0.1:8000/active/%s</a>" % (
        username, token, token)
        send_mail(subject, message, sender, receiver, html_message=html_message)
        time.sleep(3)

    views.py

    from django.shortcuts import render,redirect,HttpResponse
    
    from django.core.urlresolvers import reverse
    from django.views.generic import View
    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    from itsdangerous import SignatureExpired
    from django.conf import settings
    from celery_tasks.tasks import send_register_active_email
    from app01.models import User
    from django.contrib.auth import authenticate,login,logout
    
    import re
    # Create your views here.
    
    ##########注册第一种FBV模式#########
    #注册和注册处理合一起
    def register1(request):
        if request.method == "GET":
            return render(request,'register.html')
        else:
            username = request.POST.get("user_name")
            password = request.POST.get("pwd")
            re_password = request.POST.get("cpwd")
            email = request.POST.get("email")
            allow = request.POST.get("allow")
    
            if not all([username, password, re_password, email]):
                return render(request, 'register.html', {"errmsg": '数据不完整'})
            # 第一种校验用户名
            # name_exist= models.User.objects.filter(username=username)
            # if name_exist:
            #     return render(request, 'register.html', {"error": '用户名已存在'})
            # 第二种校验用户名
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # 用户名不存在
                user = None
            if user:
                return render(request, 'register.html', {"errmsg": '用户名已存在'})
    
            if not re.match(r'^[a-z0-9][w.-]*@[a-z0-9-]+(.[a-z]{2,5}){1,2}$', email):
                return render(request, 'register.html', {"error": '邮箱格式不正确'})
            if allow != "on":
                return render(request, 'register.html', {"errmsg": '请同意协议'})
    
            user = User.objects.create_user(username=username, password=password, email=email)
            # django内置的user中有一个is_active,注册成功默认激活,这里不认他激活
            user.is_active = 0
            user.save()
    
    
            return redirect(reverse('goods:index'))
    
    #注册和注册处理分开写
    # def register_handle(request):
    #     username = request.POST.get("user_name")
    #     password = request.POST.get("pwd")
    #     re_password = request.POST.get("cpwd")
    #     email = request.POST.get("email")
    #     allow = request.POST.get("allow")
    #
    #     if  not all([username,password,re_password,email]):
    #         return render(request,'register.html',{"error":'数据不完整'})
    #     #第一种校验用户名
    #     # name_exist= models.User.objects.filter(username=username)
    #     # if name_exist:
    #     #     return render(request, 'register.html', {"error": '用户名已存在'})
    #     #第二种校验用户名
    #     try:
    #         user = models.User.objects.get(username=username)
    #     except models.User.DoesNotExist:
    #         #用户名不存在
    #         user=None
    #     if user:
    #         return render(request, 'register.html', {"error": '用户名已存在'})
    #
    #     if not re.match(r'^[a-z0-9][w.-]*@[a-z0-9-]+(.[a-z]{2,5}){1,2}$',email):
    #         return render(request, 'register.html', {"error": '邮箱格式不正确'})
    #     if allow != "on" :
    #         return render(request, 'register.html', {"error": '请同意协议'})
    #
    #     user = models.User.objects.create_user(username=username,password=password,email=email)
    #     #django内置的user中有一个is_active,注册成功默认激活,这里不认他激活
    #     user.is_active = 0
    #     user.save()
    #     return redirect(reverse('goods:index'))
    
    ##########注册第二种CBV模式#####
    
    class RegisterView(View):
        def get(self,request):
            return render(request, 'register.html')
    
        def post(self,request):
            print("=========")
            username = request.POST.get("user_name")
            password = request.POST.get("pwd")
            re_password = request.POST.get("cpwd")
            email = request.POST.get("email")
            allow = request.POST.get("allow")
            print(username,password,re_password,email)
    
            if not all([username, password, re_password, email]):
                return render(request, 'register.html', {"errmsg": '数据不完整'})
            # 第一种校验用户名
            # name_exist= models.User.objects.filter(username=username)
            # if name_exist:
            #     return render(request, 'register.html', {"error": '用户名已存在'})
            # 第二种校验用户名
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # 用户名不存在
                user = None
            if user:
                return render(request, 'register.html', {"errmsg": '用户名已存在'})
    
            if not re.match(r'^[a-z0-9][w.-]*@[a-z0-9-]+(.[a-z]{2,5}){1,2}$', email):
                return render(request, 'register.html', {"errmsg": '邮箱格式不正确'})
            if allow != "on":
                return render(request, 'register.html', {"errmsg": '请同意协议'})
    
            user = User.objects.create_user(username=username, password=password, email=email)
            # django内置的user中有一个is_active,注册成功默认激活,这里不认他激活
            user.is_active = 0
            user.save()
    
            #发送激活邮件,激活连接地址http://127.0.0.1:8000/user/active/2
            #激活连接中要有用户的身份信息,为了防止恶意激活,要对用户信息加密
            #加密用户信息,生成激活token
            serialize = Serializer(settings.SECRET_KEY,3600)
            info = {"confirm":user.id}
            token = serialize.dumps(info) #byte类型
            token = token.decode() #转成utf8
    
            #发送邮件
            send_register_active_email.delay(email,username,token)
    
    
            return redirect('/index')
    
    #激活视图
    class ActiveView(View):
        def get(self,request,token):
            serialize = Serializer(settings.SECRET_KEY, 3600)
            try:
                info = serialize.loads(token)   #解密
                #获取待激活的用户id
                user_id = info['confirm']
                user = User.objects.get(id=user_id)
                user.is_active = 1
                user.save()
                #激活成功,返回登录页面
                return redirect('/login')
    
            except SignatureExpired as e:
                return HttpResponse("激活链接已过期")
    
    class LoginView(View):
        def get(self,request):
            '''显示登录页面'''
            # 判断是否记住了用户名
            if 'username' in request.COOKIES:
                username = request.COOKIES.get("username")
                checked = 'checked' #勾选记住用户名
            else:
                username = ''
                checked = ''
            return render(request,'login.html',{'username':username,'checked':checked})
    
        def post(self,request):
            #登录校验
            username = request.POST.get("username")
            password = request.POST.get("pwd")
    
            if not all([username,password]):
                return render(request,'login.html',{'errmsg':"数据不完整"})
    
            user = authenticate(username=username,password=password)
            if user is not None:
                #判断用户是否激活
                if user.is_active:
                    login(request, user)  #login()使用Django的session框架来将用户的ID保存在session中
                    #默认跳转到主页,即如果用户直接在login登录则默认跳转主页,如果其他页面转到,则跳转之前页面
                    next_url = request.GET.get("next",reverse('index'))
                    response = redirect(next_url)#跳转到首页
                    remember = request.POST.get("remember")
                    if remember == "on":
                        #记住用户名
                        response.set_cookie('username',username,max_age=7*24*3600)
                    else:
                        response.delete_cookie('username')
                    return response
                else:
                    return render(request, 'login.html', {'errmsg': "用户未激活"})
            else:
                return render(request, 'login.html', {'errmsg': "用户名或密码错误"})
    
    # /user/logout
    class LogoutView(View):
        '''退出登录'''
        def get(self, request):
            '''退出登录'''
            # 清除用户的session信息
            logout(request)
    
            # 跳转到首页
            return redirect(reverse('index'))
    
    
    class IndexView(View):
        def get(self, request):
            '''退出登录'''
            # 清除用户的session信息
    
    
            # 跳转到首页
            return render(request,'index.html')

    url.py

    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^register$',views.RegisterView.as_view(),name='register'),#第一种FBV
        url(r'^active/(?P<token>.*)$',views.ActiveView.as_view(),name='active'),
        url(r'^login$',views.LoginView.as_view(),name='login'),
        url(r'^logout$', views.LogoutView.as_view(), name='logout'), # 注销登录
        url(r'^index$', views.IndexView.as_view(), name='index'), # 注销登录
    ]
  • 相关阅读:
    python格式化输出之format用法
    Mybatis插入数据返回主键
    DBC 和 Mybatis连接mysql数据库的时候,设置字符集编码
    工具列表
    Idea的Git如何回退到上一个版本
    mybatis-plus id主键生成的坑
    JAVA 线上故障排查完整套路,从 CPU、磁盘、内存、网络、GC 一条龙!
    DDD-快速hold住业务的利器
    深入理解ThreadLocal的原理和内存泄漏问题
    VUE开发--环境配置
  • 原文地址:https://www.cnblogs.com/chvv/p/10416033.html
Copyright © 2011-2022 走看看