1. 程式人生 > >Django實現驗證碼

Django實現驗證碼

和php的思路差不多,先用繪圖的庫生成驗證碼,然後通過session儲存,最後post提交驗證。

目錄樹

.
├── db.sqlite3
├── manage.py
├── SchoolBuy
│ ├── init.py
│ ├── settings.py
│ ├── urls.py
│ ├── utils
│ │ ├── check_code.py
│ ├── views.py
│ └── wsgi.py
└── templates
└── test_code.html

用PIL生成驗證碼

check_code.py

import random,string
from PIL import Image,ImageDraw,ImageFont,ImageFilter

#生成隨機字串
def getRandomChar():
    #string模組包含各種字串,以下為小寫字母加數字
    ran = string.ascii_lowercase+string.digits
    char = ''
    for i in range(4):
        char += random.choice(ran)
    return char

#返回一個隨機的RGB顏色
def getRandomColor
():
return (random.randint(50,150),random.randint(50,150),random.randint(50,150)) def create_code(): #建立圖片,模式,大小,背景色 img = Image.new('RGB', (120,30), (255,255,255)) #建立畫布 draw = ImageDraw.Draw(img) #設定字型 font = ImageFont.truetype('Arial.ttf', 25) code = getRandomChar() #將生成的字元畫在畫布上
for t in range(4): draw.text((30*t+5,0),code[t],getRandomColor(),font) #生成干擾點 for _ in range(random.randint(0,50)): #位置,顏色 draw.point((random.randint(0, 120), random.randint(0, 30)),fill=getRandomColor()) #使用模糊濾鏡使圖片模糊 img = img.filter(ImageFilter.BLUR) #儲存 #img.save(''.join(code)+'.jpg','jpeg') return img,code if __name__ == '__main__': create_code()

設定存放圖片的地址

views.py(部分)

from SchoolBuy.utils import check_code
from io import BytesIO
from django.http import HttpResponse,Http404

def create_code_img(request):
    #在記憶體中開闢空間用以生成臨時的圖片
    f = BytesIO()
    img,code = check_code.create_code()
    request.session['check_code'] = code
    img.save(f,'PNG')
    return HttpResponse(f.getvalue())

utls.py(部分)

url(r'^create_code/$',views.create_code_img),
  • 解析
    在記憶體中開闢空間存放圖片,並將session中的值更新,將圖片傳送個一個連結,這裡用到”create_code/”

顯示圖片及判斷

test_code.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>測試驗證碼</title>
</head>
<body>
<form method="post" action="#">
    {% csrf_token %}
    <img id="check_code_img" src="/create_code/" onclick="refresh_check_code(this)">
    <input type="text" name="code">
    <input type="submit">
</form>

<script>
    function refresh_check_code(ths) {
        ths.src += '?';
        //src後面加問好會自動重新整理驗證碼img的src
}
</script>

</body>
</html>
<script> 是用來重新整理圖片的
表單用post方法傳送
{% csrf_token %} django用來防止跨站指令碼攻擊的解決辦法
<img> 標籤內的地址為剛才設定的地址

views.py(部分)

from django.shortcuts import render_to_response,render
def test_code(request):
    #GET方法返回表單
    if request.method == 'GET':
        return render(request,'test_code.html')
    #POST方法用來驗證提交的驗證碼是否正確
    else:
        code = request.POST.get('code','')
        if code == request.session.get('check_code','error'):
            return HttpResponse("yes")
        return HttpResponse("no")

urls.py(部分)

url(r'^$',views.test_code),

至此,驗證碼檢驗已完成

可能遇到的問題

  • session無法使用
    預設情況建django是自動開啟session的,使用資料庫實現,如果提示沒有django_session資料表,則通過下面方法解決
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser