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 = ‘天猫商城
创建一个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 = "%s欢迎成为会员
请点击以下链接激活账户http://127.0.0.1:8000/active/%s" % (
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
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‘), # 注销登录
]