1. 程式人生 > >celery使用發送郵件激活

celery使用發送郵件激活

style name 異步執行 gist byte dex 24* 校驗 錯誤

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 = [email protected] #在郵箱中設置的客戶端授權密碼 EMAIL_HOST_PASSWORD = xxxxxxxxx #收件人看到的發件人 EMAIL_FROM = 天貓商城<[email protected]>

創建一個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://:[email protected]: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), # 註銷登錄
]

celery使用發送郵件激活