""" 用户登录视图 """ 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/')