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 }}>就可以了。
注意:以上所有需要指定模組版本的一定要指定!