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 }}>就可以了。

注意:以上所有需要指定模組版本的一定要指定!