一、登录的基本流程:
登录 —username -password -验证码: -前段向后台发送图片请求 -后台生成一张图片 -因为图片不应该存到磁盘所以导入io模块的BytesIO把图片存到内存 -用PIL模块中的Image生成一张图片 -用PIL模块中的ImageDraw给图片加文字 -用PIL模块中的ImageFont给文字添加样式 -导入random模块,生成的图片是随机的 -生成图片的同时将生成的随机字符存入valid_list -用二进制的方法打开图片 —赋值给data -将valid_list转换为字符串赋值给valid_str -将valid_str存入session中便于验证键为:keepValidCode 值为:valid_str -将data返回给前端进行渲染 -提交 -给提交按钮绑定事件 -发送ajax请求: -url为/login/ -请求方式为POST -将data发送到后端 -data里面存放用户名,密码,验证码的值 -后端接收请求判断是否为ajax -如果是ajax -拿出request中的用户名,密码,验证码 -首先拿出request中的验证码与session中keepValidCode的值进行比对 -如果验证码比对成功则进行用户名和密码比对 -全部比对成功则将login_response中is_login值设为True -将login_reponse进行序列化发送给前端 -执行ajax中的success -接收后台响应数据data -将data进行反序列化 -is_login的值为True进入index界面 -否则对data中的error_msg进行渲染 -如果比对出错 -将错误信设成login_response中error_msg的值 -将login_reponse序列化发送到前端 -如不是ajax 返回登录界面
代码演示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <script src="/static/dist/js/jquery-3.1.1.js"></script> <script src="/static/dist/js/bootstrap.js"></script> <link rel="stylesheet" href="/static/dist/css/bootstrap.css"> <style> .hides{ display: none; } </style> </head> <body> <nav class="navbar navbar-inverse"> <div class="container"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">博客园</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> <ul class="nav navbar-nav navbar-right"> {% if request.user.is_authenticated %} <li><a href=""><span class="glyphicon glyphicon-user"></span>{{ request.user.username }}</a></li> <li><a href="/logout/">注销</a></li> {% else %} <li><a href="/login/">登录</a></li> <li><a href="/reg/">注册</a></li> {% endif %} <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container"> <div class="row"> <div class="col-md-2"> <div class="panel panel-primary"> <div class="panel-body"> 网站分类 </div> <div class="panel-footer"> {% for cate in cate_list %} <div class="panel panel-default"> <div class="panel-body cate_title">{{ cate.name }}</div> <div class="panel-footer hides"> {% for sitearticlecategory in cate.sitearticlecategory_set.all %} <p><a href="/cate/{{ sitearticlecategory.name }}">{{ sitearticlecategory.name }}</a></p> {% endfor %} </div> </div> {% endfor %} </div> </div> </div> <div class="col-md-7"> <div class="article_list"> {% for article in article_list %} <div class="article_item"> <div class="title"><a href="#">{{ article.title }}</a></div> <div class="row"> <div class="avatar col-md-2"> <a href="{% url 'aaa' article.user.username %}"><img src="{{ article.user.avatar.url }}" alt="" width="60" height="60"></a> </div> <div class="col-md-10"> <p>{{ article.desc }}</p> </div> </div> <div class="pub_info row"> <a href="/blog/{{ article.user.username }}">{{ article.user.username }}</a> 发布于 {{ article.create_time|date:"Y-m-d H:i" }} <a href=""><span class="glyphicon glyphicon-comment"></span>评论({{ article.comment_count }})</a> <a href=""><span class="glyphicon glyphicon-thumbs-up"></span>点赞({{ article.up_count }})</a> </div> </div> <p></p> {% endfor %} </div> </div> <div class="col-md-3"> <div class="panel panel-info"> <div class="panel-body"> Panel content </div> <div class="panel-footer">Panel footer</div> </div> <div class="panel panel-warning"> <div class="panel-body"> Panel content </div> <div class="panel-footer">Panel footer</div> </div> <div class="panel panel-success"> <div class="panel-body"> Panel content </div> <div class="panel-footer">Panel footer</div> </div> </div> </div> </div> <script> $(".cate_title").mouseover(function () { $(this).next().slideDown(300) }).parent().mouseleave(function () { $(this).children(".panel-footer").slideUp(300) }) </script> </body> </html>
def login(request): # if request.is_ajax(): if request.is_ajax(): username=request.POST.get("username") password=request.POST.get("password") validCode=request.POST.get("validCode") login_response={"is_login":False,"error_msg":None} if validCode.upper()==request.session.get("keepValidCode").upper(): user=auth.authenticate(username=username,password=password) if user: login_response["is_login"]=True request.session["username"]=username else: login_response["error_msg"] = "username or password error" else: login_response["error_msg"]='validCode error' import json return HttpResponse(json.dumps(login_response)) return render(request,"login.html")
二、注册的基本流程:
注册流程: form(在注册页面生成Html标签定规则,检测用户输入信息,打包正确信息) 定义规则: -username -password -repeat_pwd -email 注册: Form生成标签 -username -password -repeat_pwd -email avatar不是Form生成的 <div class="form-group avatar">#设为父级标签在样式中加入position:relative相对定位 <label for="avatar">头像</label> <img src="/static/img/default.png" alt="" id="avatar_img"> <input type="file" class="form-control" id="avatar_file" > #给img和input的样式都加上position:absolute设为绝对定位然后设置它们的大小一致,这样就导致这两个标签会遮住label标签,所以将它们向右移一定距离 给input标签设置透明度为0,显示出img </div> 头像预览 - 用户点击上传文件 上传文件的标签发生变化,会触发change事件 - 取到用户上传的文件 var ele_file = this.files[0]; - 创建FileReader()对象 - 把上传文件的对象的路径写入FileReader()对象,结果为FileReader().result - FileReader()加载onload事件,把FileReader().result结果写入到img标签 -提交 -submit -提交绑定click事件 -由于头像是以二进制进行传的: 在传二进制的时候必须要到的参数 -contentType:false, -processData:false, -headers:{"X-CSRFToken":$.cookie('csrftoken')},防止跨站请求 -用FormData打包数据 var formdata=new FormData(); formdata.append("username",$("#id_username").val()); -通过data把数据传到后台函数 -发送ajax请求 请求url:/reg/ 请求方式:POST 发送数据:formdata 后端reg接收请求: -如果请求是ajax -定义form_obj接收前端发过来的数据进行验证 -定义一个字典regRespones用来保存用户名和错误信息 -如果数据验证成功 -将数据赋值给各变量 -在用户表中创建一条新记录 -将用户名存入字典中的user中 -否则直接将错误信息存入字典中的errorsList中 -将字典regResponse进行序列化后发送至前端 执行前端ajax中的success -先将data反序列化 -data中user有值的话 -进入登录页面 -否则循环遍历errorsList $.each(data.errorsList,function (i,j) { // i j - username ["用户名不能为空"] - repeat_pwd ["验证密码不能为空"] - email ["邮箱不能为空"]0 $span=$("<span>"); $span.addClass("pull-right").css("color","red"); -{# 添加一个span标签#} $span.html(j[0]); -{#把log的值j写入span中#} $("#id_"+i).after($span).parent().addClass("has-error") -#id_"+i找到当前的错误的input框 -parent().addClass("has-error")给错误的input框加一个红色的颜色 if (i=="__all__"){ $("#id_repeat_pwd").after($span) -全局钩子的错误信息 } })
代码演示:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> <script src="/static/dist/js/jquery-3.1.1.js"></script> <script src="/static/dist/js/bootstrap.js"></script> <link rel="stylesheet" href="/static/dist/css/bootstrap.css"> <link rel="stylesheet" href="/static/css/reg.css"> <script src="/static/js/jquery.cookie.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-5 col-md-offset-3"> <form> {% csrf_token %} <div class="form-group"> <label for="username">用户名</label> {{ form_obj.username }} </div> <div class="form-group"> <label for="password">密码</label> {{ form_obj.password }} </div> <div class="form-group"> <label for="password">确认密码</label> {{ form_obj.repeat_pwd }} </div> <div class="form-group"> <label for="email">邮箱</label> {{ form_obj.email }} </div> <div class="form-group avatar"> <label for="avatar">头像</label> <img src="/static/img/default.png" alt="" id="avatar_img"> <input type="file" class="form-control" id="avatar_file" > </div> <input type="button" value="submit" class="btn btn-primary" id="subBtn"><span class="error"></span> </form> </div> </div> </div> <script> // 头像预览 $("#avatar_file").change(function () { var ele_file=$(this)[0].files[0]; //this.files var reader=new FileReader(); reader.readAsDataURL(ele_file); reader.onload=function () { $("#avatar_img")[0].src=this.result } }); $("#subBtn").click(function () { var formdata=new FormData(); formdata.append("username",$("#id_username").val()); formdata.append("password",$("#id_password").val()); formdata.append("repeat_pwd",$("#id_repeat_pwd").val()); formdata.append("email",$("#id_email").val()); formdata.append("avatar_img",$("#avatar_file")[0].files[0]); $.ajax({ url:"/reg/", type:'POST', data:formdata, contentType:false, processData:false, headers:{"X-CSRFToken":$.cookie('csrftoken')}, success:function (data) { console.log(data); var data=JSON.parse(data); if (data.user){ location.href="/login/" } else { console.log(data.errorsList); $.each(data.errorsList,function (i,j) { console.log(i,j); $span=$("<span>"); $span.addClass("pull-right").css("color","red"); $span.html(j[0]); $("#id_"+i).after($span).parent().addClass("has-error") if (i=="__all__"){ $("#id_repeat_pwd").after($span) } }) } } }) }) </script> </body> </html>
def reg(request):
if request.is_ajax():
form_obj=forms.RegForm(request,request.POST)
print(form_obj)
regResponse={"user":None,"errorsList":None}
if form_obj.is_valid():
username=form_obj.cleaned_data["username"]
password=form_obj.cleaned_data["password"]
email=form_obj.cleaned_data.get("email")
avatar_img=request.FILES.get("avatar_img")
user_obj=models.UserInfo.objects.create_user(username=username,password=password,email=email,avatar=avatar_img,nickname=username)
print(user_obj.avatar,"......")
regResponse["user"]=user_obj.username
else:
regResponse["errorsList"]=form_obj.errors
import json
return HttpResponse(json.dumps(regResponse))
form_obj=forms.RegForm(request)
return render(request,"reg.html",{"form_obj":form_obj})
.container{ margin-top: 100px; } .avatar{ position: relative; width: 60px; height: 60px; } #avatar_img,#avatar_file{ position: absolute; top: 0; left: 80px; width: 60px; height: 60px; } #avatar_file{ opacity: 0; }