django_project_demo/app/views/account.py

125 lines
4.1 KiB
Python
Raw Normal View History

2024-08-24 11:25:23 +08:00
"""
用户登录视图
"""
from django.shortcuts import render, HttpResponse, redirect
from django import forms
from app import models
from app.utils.bootstrap import BootstrapForm, BootstrapModelForm
from app.utils.code import check_code # 验证码
from app.utils.encrypt import md5
from io import BytesIO # 用于在内存中生成文件,验证码用
"""
两种实现方式
1.LoginForm 是用Form实现字段需要自己写
2.LoginModelForm 是用ModelForm实现字段可以从数据库(models)中获取
"""
"""登录窗体"""
class LoginForm(BootstrapForm):
username = forms.CharField(
label='用户名',
widget=forms.TextInput,
required=True, # 必填
)
password = forms.CharField(
label='密码',
widget=forms.PasswordInput(render_value=True), # render_value 不清空密码
required=True, # 必填
)
img_code = forms.CharField(
label='验证码',
widget=forms.TextInput,
required=True, # 必填
)
# 钩子方法猎取密码的md5值
def clean_password(self):
pwd = self.cleaned_data.get('password')
return md5(pwd)
# 这个类没有用到,因为登录界面就两个输入框 简单所以用Form实现
class LoginModelForm(BootstrapModelForm):
class Meta:
models = models.Admin
fields = ['username', 'password']
""" 用户登录 """
def login(request):
if request.method == 'GET':
form = LoginForm()
return render(request, 'login.html', {'form': form})
form = LoginForm(data=request.POST)
if form.is_valid():
# 验证成功,获取到用户名和密码
# form.cleaned_data本身是一个字典
print(form.cleaned_data)
# 验证码校验
# 取出用户输入的验证码并且从cleaned_data字典中删除确保在数据库验证中不携带验证码
user_input_imgcode = form.cleaned_data.pop('img_code')
code = request.session.get('img_code', '')
if code.upper() != user_input_imgcode.upper():
form.add_error('img_code', '验证码错误')
return render(request, 'login.html', {'form': form})
# 查询数据库中的用户名,没查到返回None
# 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()
print(admin_object) # 验证通过后所有数据都在form.cleaned_data
if not admin_object:
# 主动在password下展示错误信息
form.add_error('password', '用户名或密码错误')
return render(request, 'login.html', {'form': form})
# 正确输入
# 这里就要用到cookie和session的知识了
# 1.先生成一个随机字符 2.写入到本地浏览器的cookie中 3.再写入到服务器(网站)的session中
# 但django帮我们简化成了
# request.session['info'] = admin_object.username # 可以存入一个值
request.session['info'] = {'id': admin_object.id, 'username': admin_object.username}
# 如果登录成功session会保存7天免登录
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect('/admin/list')
# return HttpResponse('提交成功')
return render(request, 'login.html', {'form': form})
""" 生成图片验证码 """
def image_code(request):
# 生成图片验证码图像和字符串
img, code_str = check_code()
# 把验证码写入到session中
request.session['img_code'] = code_str
request.session.set_expiry(60) # 设置session变量的60s超时
# 写入内存
stream = BytesIO() # 在内存中生成文件
img.save(stream, 'png') # 把生成的img验证码写入到内存文件中
return HttpResponse(stream.getvalue())
# 4. 写入内存Python2
# import StringIO
# stream = StringIO.StringIO()
# img.save(stream, 'png')
# stream.getvalue()
""" 注销用户 """
def loginout(request):
request.session.clear()
return redirect('/login/')