一、登录页面
效果图:
制作验证码
验证码:验证码这个功能用了Image,ImageDraw,ImageFont,random,BytesIO模块和session
Image是新创建一个图片,ImageDraw相当于在这个图片上创建一个画笔,ImageFont指定字体的格式
random随机模块,BytesIO开辟一片字节类型的内存空间,session用于存储验证码
import random from PIL import Image,ImageDraw,ImageFont,ImageFilter from io import BytesIO # 能够帮你保存数据 并且在取的时候会以二进制的形式返回给你 #登录 #随机生成RGB值 def rndColor2(): return(random.randint(32,127),random.randint(32,127),random.randint(32,127)) #随机生成RGB值 def rndColor(): return(random.randint(64,255),random.randint(64,255),random.randint(64,255)) def get_code(request): img_obj = Image.new('RGB', (310,35), (255, 255, 255)) #生成一个画笔对象 img_draw = ImageDraw.Draw(img_obj) #生成一个字体对象 img_font = ImageFont.truetype('static/fonts/tahoma.ttf',36) # 填充每个像素点 for x in range(310): for y in range(35): img_draw.point((x, y), fill=rndColor()) #随机验证码:数字,小写字母,大写字母 code = ''#定义一个变量存储最终的验证码 for i in range(4): random_int = str(random.randint(0,9)) random_upper = chr(random.randint(65,90)) random_lower = chr(random.randint(97,122)) temp_code = random.choice([random_int,random_upper,random_lower]) #将产生的字一个一个写在图片上 img_draw.text((60+i*45,-5), temp_code, rndColor2(), img_font) #code记录 code += temp_code #将code放到session中 request.session['code'] = code #生成io对象 io_obj = BytesIO() #图片模糊 img_obj = img_obj.filter(ImageFilter.BLUR) img_obj.save(io_obj,'png') return HttpResponse(io_obj.getvalue())
登录验证
1、需要从数据库中拿到username和passwoed做比对,因为数据库中password存的是密文需要用到auth模块
user=auth.authenticate(request,username=username,password=password)
如果user存在,登录成功,保持登录状态,否则返回错误信息,并对前端进行渲染
登录成功
首先用auth.login把user绑定,相当于session和cookie但是使用方法比这两个都简单,执行之后,不退出登录的情况下,request.user就是auth.login(request,user)里面的user
auth.login(request,user)
登录成功之后,给前端返回数据,首先在函数开头定义一个back_dic用于标识成功或失败
back_dic={'code':100,'msg':''}
当登录成功的时候,code不变,给response添加一个URL:
back_dic['url']='/home/'
当登录成功的时候,跳转到home页面。当然了这行代码也需要前端的配合,前端:
success:function (data) { if(data.code==100){ location.href=data.url }
登录失败
登录失败,back_dic['code']变为101(或者随意一个数,和成功区别开就好),msg变为失败的信息,比如是验证码出错还是账号密码错误
流程图
登录代码:
#登录 def login(request): back_dic = {'code':100,'msg':''} # 判断是ajax请求还是正常form表单请求 request.is_ajax() if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') code = request.POST.get('code') #先校验验证码统一转成大写或者小写 if code.upper() == request.session.get('code').upper(): user_obj = auth.authenticate(username=username,password=password) if user_obj: #登陆成功记录用户状态 auth.login(request,user_obj) back_dic['msg'] = '登录成功!' back_dic['url'] = '/home/' else: back_dic['code'] = 102 back_dic['msg'] = '用户名密码错误!' else: back_dic['code'] = 103 back_dic['msg'] = '验证码错误!' return JsonResponse(back_dic) return render(request,'login.html')
登录前端代码:
{% extends 'base.html' %} {% block css %} <style> body { background-image: url('../static/image/register.jpg'); background-repeat: no-repeat; background-size: 100% 100%; background-attachment: fixed; } .wrap { height: 550px; width: 500px; position: fixed; {#background-color: #eeeeee;#} background-color: rgba(238, 238, 238, 0.7); top: 20%; right: auto; } #t1 { padding-top: 10px; } label { width: 400px; margin: 5px 50px; } #b1 { width: 80%; margin: 10px auto; } </style> {% endblock %} {% block content %} <div class="container-fluid"> <div class="row"> <div class="col-md-4 col-md-offset-4"> <div class="wrap"> <h2 class="text-center" id="t1">登录页面</h2> <hr> {% csrf_token %} <div class="form-group"> <label for="id_username">用户名 <input type="text" class="form-control" name="username" id="id_username"></label> </div> <div class="form-group"> <label for="id_password">密码 <input type="password" class="form-control" name="password" id="id_password"></label> </div> <div class="form-group"> <label for="id_code">验证码 <input type="text" class="form-control" name="code" id="id_code"> <br> <img src="/get_code/" alt="" width="250" height="50" id="i1"> <br> <a href="javascript:refreshcode();" id="id_img">看不清,换一张 </a> </label> </div> <div> <label for="c1"><input type="checkbox" id="c1">记住密码 <a href="{% url 'register' %}" class="pull-right">立即注册</a></label> </div> <div id="b1"> <button class="pull-right btn btn-primary btn-block" id="id_submit">登录</button> <span class="errors" style="color: red" id="id_error"></span> </div> </div> </div> </div> </div> <script type="text/javascript" color="255,255,255" opacity='1' zIndex="-2" count="150" src="//cdn.bootcss.com/canvas-nest.js/1.0.1/canvas-nest.min.js"></script> {% endblock %} {% block script %} <script> $('#id_img').click(function () { //*获取图片src旧路径 let oldPath = $('#i1').attr('src'); //修改src属性 $('#i1').attr('src', oldPath += '?') }); $('#id_submit').click(function () { $.ajax({ url: '', type: 'post', data: { 'username': $('#id_username').val(), 'password': $('#id_password').val(), 'code': $('#id_code').val(), 'csrfmiddlewaretoken': '{{ csrf_token }}', }, success: function (data) { if (data.code == 100) { location.href = data.url } else { $('#id_error').html(data.msg) } } }) }); $('input').focus(function () { $('#id_error').html('') }) </script> {% endblock %}
首页导航条
未登入状态下
效果图:
登录状态下
效果图:
登录状态栏实现:
<li><a href="#"><i class="iconfont icon-report-Useronlinereport" style="color: #4ad867"></i>:{{ request.user.username }}</a></li>
前端也可以直接用后端request.user的方法取到用户名
退出登录
#退出登录 def logout(request): auth.logout(request) return redirect('/home/')
修改密码
效果图:
首先后端先获取到前端的旧密码,新密码,确认密码,用auth模块中的check_password判断旧密码是否正确,然后判断两次新密码是否一致,用set_password设置新密码
后端代码:
#修改密码 def set_password(request): back_dic ={'code':100,'msg':''} if request.method =='POST': old_password = request.POST.get('old_password') new_password = request.POST.get('new_password') confirm_password = request.POST.get('confirm_password') #判断旧密码正不正确 res = request.user.check_password(old_password) #如果为True就修改密码 if res: #再比对两次密码一致不一致 if new_password == confirm_password: request.user.set_password(new_password) request.user.save() back_dic['msg'] = '密码修改成功!' back_dic['url'] = '/login/' else: back_dic['code'] = 102 back_dic['msg'] = '两次密码不一致!' else: back_dic['code'] = 103 back_dic['msg'] = '旧密码输入有误!' return JsonResponse(back_dic) return render(request,'set_password.html',locals())
前端代码:
{% extends 'base.html' %} {% block css %} <style> body { background-color: #eeeeee; } label { width: 400px; margin: 5px 50px; } </style> {% endblock %} {% block content %} <div class="container-fluid"> <div class="row"> <div class="col-md-4 col-md-offset-4"> {% csrf_token %} <h2 class="text-center">修改密码</h2> <div class="form-group"> <label for="id_username">用户名 <input type="text" name="username" class="form-control" id="id_username" disabled value="{{ request.user.username }}"> </label> </div> <div class="form-group"> <label for="id_old_password">旧密码 <input type="password" name="old_password" class="form-control" id="id_old_password"> </label> </div> <div class="form-group"> <label for="id_new_password">密码 <input type="password" name="new_password" class="form-control" id="id_new_password"> </label> </div> <div class="form-group"> <label for="id_confirm_password">确认密码 <input type="password" name="confirm_password" class="form-control" id="id_confirm_password"> </label> </div> <label for="id_button"> <button class="btn btn-primary btn-block" id="id_button">点击修改</button> <span class="errors" style="color: red" id="id_error"></span> </label> </div> </div> </div> {% endblock %} {% block script %} <script> $('#id_button').click(function () { $.ajax({ url: '', type: 'post', data: { 'old_password': $('#id_old_password').val(), 'new_password': $('#id_new_password').val(), 'confirm_password': $('#id_confirm_password').val(), 'csrfmiddlewaretoken':'{{ csrf_token }}', }, success: function (data) { if (data.code == 100) { location.href = data.url } else { $('#id_error').html(data.msg) } } }) }); $('input').focus(function () { $('#id_error').html('') }) </script> {% endblock %}