一.项目演示
演示视频
二.代码层级
三.部分代码示例
account.py(登录视图函数)
from django.shortcuts import HttpResponse, render, redirect
from django import forms
from io import BytesIO
from app01 import models
from app01.utils.bootstrap import BootstrapForm
from app01.utils.encrypt import md5
from app01.utils.code import check_code
class LoginForm(BootstrapForm):
username = forms.CharField(
label="用户名",
widget=forms.TextInput,
required=True
)
password = forms.CharField(
label="密码",
widget=forms.PasswordInput(render_value=True),
required=True # 默认不为空
)
code = forms.CharField(
label="验证码",
widget=forms.TextInput,
required=True
)
def clean_password(self):
pwd = self.cleaned_data.get('password')
return md5(pwd)
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():
# 验证成功后,获取的提交信息
# {'username': 'linke', 'password': '123'}
# print(form.cleaned_data)
# 去数据库校验,获取用户对象 存在则有对象,不存在则None
# admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'],
# password=form.cleaned_data["password"]).first()
# 验证码的校验
user_image_code = form.cleaned_data.pop('code')
code = request.session.get('image_code', '')
if code.upper() != user_image_code.upper():
form.add_error("code", "验证码错误")
return render(request, 'login.html', {"form": form})
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:
# 网站随机生成一个字符现串,写到用户浏览器的cookie中,再写入到session中
request.session["info"] = {"id": admin_object.id, "name": admin_object.username}
# 登陆成功,重新设置session超时失效时间,保存7天
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect('/admin/list/')
else:
return render(request, 'login.html', {"form": form})
def image_code(request):
""" 生成图片验证码 """
# 调用pillow函数,生成图片
img, code_string = check_code()
# 写入到自己的session中,以便后续获取验证码再进行校验
request.session['image_code'] = code_string
# 给session设置60s超时 ,60s之后失效 【注意:登陆成功后,重新设置session失效时间】
request.session.set_expiry(60)
stream = BytesIO()
img.save(stream, format='png')
return HttpResponse(stream.getvalue())
def logout(request):
""" 注销 """
request.session.clear()
return redirect('/login/')
auth.py(页面访问限制)
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse, render, redirect
class AuthMiddleWare(MiddlewareMixin):
""" 中间件 """
def process_request(self, request):
# 如果方法中没有返回值,则继续往后走
# 如果有返回值 HttpResponse render redirect
# 1.排除那些不需要走该中间件的url
# request.path_info 获取当前访问的url
exclude_url_list = ['/login/', '/image/code/']
if request.path_info in exclude_url_list:
return
# 2.读取当前访问的用户的session信息,如果能读取到,说明已登录过,然后继续往后走逻辑
info_dict = request.session.get("info")
if info_dict:
return # 直接return None 继续往后走
else:
# 重新回到登录页面
return redirect('/login/')
bootstrap.py(封装bootstrap样式类)
from django import forms
class Bootstrap:
bootstrap_exclude_fields = []
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 循环ModelForm中的所有字段,给每个字段插件添加属性值
for name, field in self.fields.items():
if name in self.bootstrap_exclude_fields:
continue
# 字段中有其他属性,保留其他原来属性,没有再添加
if field.widget.attrs:
field.widget.attrs["class"] = "form-control"
field.widget.attrs["placeholder"] = field.label
else:
# 字段中没有其他属性,直接批量添加
field.widget.attrs = {
"class": "form-control",
"placeholder": field.label
}
class BootstrapModelForm(Bootstrap, forms.ModelForm):
pass
class BootstrapForm(Bootstrap, forms.Form):
pass
code.py (生成验证码)
"""
安装pillow pip3 install pillow
"""
import random
from PIL impor