celery使用發送郵件激活
阿新 • • 發佈:2019-02-22
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使用發送郵件激活