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'), # 注销登录
]
原文地址:https://www.cnblogs.com/chvv/p/10416033.html