Django實現驗證碼
阿新 • • 發佈:2019-02-19
和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