125 lines
4.1 KiB
Python
125 lines
4.1 KiB
Python
"""
|
||
用户登录视图
|
||
"""
|
||
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/')
|