Django项目(三)
- 2019 年 10 月 6 日
- 笔记
在Django中发送一个邮件是先发送给smtp服务器,smtp发送到目的邮箱,那么这个中间是有一个等待的过程,我们不想让他等待,直接跳转主页。也就是说我告诉他要去发送一封邮件,我们不用等待他发送成功!
这里要用到celery异步,当我们遇见比较耗时的操作,比如发送邮件,图片上传等,都可以用到celery。celery简单来说就是发送一个任务(比如发送一封邮件),在这中间有个任务队列,然后处理的时候,会在这个队列中一个一个处理。那么这个中间的任务队列我们需要借助RabbitMQ或者Redis数据库处理。我们就使用Redis来创建这个队列。
如何使用:
1.1、首先安装celery包:pip install celery,安装redis:pip install redis==2.10.6,安装eventlet:pip install eventlet
1.2、我们在一个项目中是经常遇见耗时的任务的,所以我们新创建一个python的包,给个名字celery_tasks,创建一个python文件tasks
1.3、在tasks.py中写上:
# 使用celery
from celery import Celery
from django.core.mail import send_mail
from django.conf import settings
# 创建一个Celery对象
# 第一个参数为一个名字,我们一般写路径
# 第二个参数为我们用来创建队列,这里用Redis数据库.
# redis://127.0.0.1:6379/3 意思是用redis数据库地址是本地的6379端口的第3个数据库
app = Celery('celery_tasks.tasks',broker='redis://127.0.0.1:6379/3')
# 定义任务函数(发送邮件)
# 写上我们需要的参数
# 加一个装饰器,为我们配置
@app.task
def send_register_email(to_email,username,token):
subject = 'python入门到放弃'
message = ''
sender = settings.EMAIL_FROM
receiver = [to_email]
html_message = '<h1>尊敬的%s,你好,欢迎注册小米商城会员。</h1>请点击下面链接激活<a href="Http://127.0.0.1:8000/xm_user/active/%s">Http://127.0.0.1:8000/xm_user/active/%s</a>' % (
username, token, token)
send_mail(subject, message, sender, receiver, html_message=html_message)
1.4、xm_user中的视图中发送邮件的代码修改成:
# 需要导入我们刚刚创建的方法
from celery_tasks.tasks import send_register_email
send_register_email.delay(email,username,token)
1.5、如何启动?
1.51、首先我们需要启动redis,上一篇启动resis的命令有误,在这里更正:
打开cmd窗口:切换到redis所在目录,执行:redis-server.exe redis.windows.conf
再打开一个cmd窗口,切换到redis目录下,执行:redis-cli.exe
1.52、启动我们的处理:再打开一个cmd窗口,进入虚拟环境,切换到xm_shop目录下,执行:celery -A celery_tasks.tasks worker -l info -P eventlet
就会看到:

1.53、再打开一个cmd窗口,运行我们的项目就可以了。
1.54、现在效果不是很明显,你会说这么麻烦,也没有什么区别,你可以再我们send_register_email添加一个睡眠时间,就会看到效果。
登录
上一篇文章说了,登录页面和主页的图片和css都没有找到,所以会很不好看,这里我们来修改一下登录页面。
2.1、首先我们打开login页面(昨天的源码中有),在head前写:{% load staticfiles %}然后所有的图片和css,等带有路径的都写成:{% static 'css/login.css' %}即可。
修改好页面之后我们需要在昨天定义的视图类中加一个post请求即可。
2.2、定义一个post函数:
def post(self,request):
username = request.POST.get('username')
password = request.POST.get('password')
if not all([username, password]):
return render(request, 'login.html', {'errmsg': '有数据为空'})
# 注册用的Django自带,验证数据当然也可以用Django自带
u = authenticate(username=username,password=password)
# 判断是否查询到数据
if u is not None:
# 判断是否激活
if u.is_active:
# Django 自带记录登录状态
login(request,u)
# 跳转到首页
return redirect(reverse("xm_goods:index"))
else:
return render(request, 'login.html', {'errmsg': '用户未激活!'})
else:
return render(request, 'login.html', {'errmsg': '用户名或密码错误!'})
2.3、由于session从mysql数据库里读取很慢,所以这里我们也用redis来保存我们的session:
2.31、上次在redis的文章中也介绍了,但是这里换一种方式:
安装模块:pip install django-redis==3.8.4
添加配置setting.py:
# 配置使用redis保存我们的session
# Django缓存配置
CACHES = {
"default":{
"BACKEND":"django_redis.cache.RedisCache",
"LOCATION":"redis://127.0.0.1:6379/4",
"OPTIONS":{
"CLIENT_CLASS":"django_redis.client.DefaultClient",
}
}
}
# session保存位置配置
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"
即可。这样我们的session就会保存在我们的redis中。
2.4、记住用户名
修改我们的视图类为:
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('password')
if not all([username, password]):
return render(request, 'login.html', {'errmsg': '有数据为空'})
# 注册用的Django自带,验证数据当然也可以用Django自带
u = authenticate(username=username,password=password)
# 判断是否查询到数据
if u is not None:
# 判断是否激活
if u.is_active:
# Django 自带记录登录状态
login(request,u)
response = redirect(reverse("xm_goods:index"))
# 获取记住用户名的状态
remember = request.POST.get('remember')
# 被点击
if remember=="on":
# 保存15天
response.set_cookie('username',username,max_age=15*24*3600)
else:
response.delete_cookie('username')
# 跳转到首页
return response
else:
return render(request, 'login.html', {'errmsg': '用户未激活!'})
else:
return render(request, 'login.html', {'errmsg': '用户名或密码错误!'})
修改login.html中账号input的value为{{username}},修改记住用户为:<input type="checkbox" name="remember" {{ checked }}>就可以了。
注意:以上所有需要指定模块版本的一定要指定!