程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

2022暑期實踐(Django教程學習記錄)(第四周6)P56圖片驗證碼(校驗)

編輯:Python

P56圖片驗證碼(校驗)

將生成的動態驗證碼存入session中:
所有用戶都訪問同一個url生成動態驗證碼,需要給不同用戶存到不同的位置

def image_code(request):
from app03_phone_number_management.utils.code import check_code
img, code_string = check_code()
# 將突變驗證碼寫入到session,設置60s過期
request.session['image_code'] = code_string
request.session.set_expiry(60)
print(code_string)
from io import BytesIO
stream = BytesIO()
img.save(stream, 'png')
return HttpResponse(stream.getvalue())

LoginForm類重寫:

class LoginForm(forms.Form):
username = forms.CharField(
label="用戶名",
widget=forms.TextInput(attrs={
'class': 'form-control'}),
required=True,
)
password = forms.CharField(
label="密碼",
widget=forms.PasswordInput(
attrs={
'class': 'form-control'},
render_value=True,
),
required=True,
)
code = forms.CharField(
label="驗證碼",
widget=forms.TextInput(
attrs={
'class': 'form-control'},
),
required=True,
)
# 在attr中向前端添加class樣式,也可以多繼承
def clean_password(self):
pwd = self.cleaned_data.get("password")
from app03_phone_number_management.utils.encrypt import md5
return md5(pwd)

對應login前端的Form自動生成驗證碼的輸入框

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄頁面</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
<style> .account {
 width: 400px; border: 1px solid #dddddd; border-radius: 5px; box-shadow: 5px 5px 20px #aaa; margin-left: auto; margin-right: auto; margin-top: 100px; padding: 20px 40px; } .account h2 {
 margin-top: 10px; text-align: center; } </style>
</head>
<body>
<div class="account">
<h2>用戶登錄</h2>
<form method="POST" novalidate>
{% csrf_token %}
<div class="form-group">
<label for="exampleInputEmail">用戶名</label>
{# <input type="text" class="form-control" placeholder="用戶名">#}
{
{ form.username }}
<span >{
{ form.username.errors.0 }}</span>
</div>
<div class="form-group">
<label>密碼</label>
{# <input type="password" class="form-control" placeholder="密碼">#}
{
{ form.password }}
<span >{
{ form.password.errors.0 }}</span>
</div>
<div class="form-group">
<label for="id_code">圖片驗證碼</label>
<div class="row">
<div class="col-xs-7">
{
{ form.code }}
<span >{
{ form.code.errors.0 }}</span>
</div>
<div class="col-xs-5">
<img id="image_code" src="/image_code/" >
</div>
</div>
</div>
<input type="submit" value="登 錄" class="btn btn-primary">
</form>
</div>
</body>
</html>

登錄邏輯加入驗證碼校驗邏輯:
!!!一定要把session超時時間改回來

def login(request):
if request.method == 'GET':
form = LoginForm()
return render(request, 'login.html', {
'form': form})
# else:
form = LoginForm(data=request.POST)
if form.is_valid():
# 校驗驗證碼
# 使用pop方法的原因:在數據庫中檢驗沒有code字段,校驗完要剔除
user_input_code = form.cleaned_data.pop('code')
code = request.session.get('session', "")
if code.upper() != user_input_code.upper():
form.add_error('code', "驗證碼錯誤")
return render(request, 'login.html', {
'form': form})
# test
# print(form.cleaned_data)
# return HttpResponse('提交成功')
# 驗證校驗:
# admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'], password=form.cleaned_data['password']).first()
# 定義類時的字段名要和數據庫中的一致
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
form.add_error("password", "用戶名或密碼錯誤")
return render(request, 'login.html', {
'form': form})
# else用戶名正確:
request.session['info'] = {

'id': admin_object.id,
'name': admin_object.username,
}
# 7天免登錄
request.session.set_expiry(60*60*24*7)
return redirect('/admin_list/')
# else:
return render(request, 'login.html', {
'form': form})

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved