【实战演练】Python+Django网站开发系列08-JavaScript/JQuery前后端交互
#本文欢迎转载,转载请注明出处和作者
1、修改密码
编辑mopasswd.html页面,使用magicbox快速拖拉拽出一个前端页面(主要是form表单),然后将代码粘贴进html页面进行修改。
如果忘记了magixbox前端页面的使用,可以参考之前文章:
<form class="form-horizontal" method="post">
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">原密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="oldpassword" placeholder="请输入原密码">
</div>
</div>
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">新密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="newpassword1" placeholder="请输入新密码">
</div>
</div>
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">确认新密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="newpassword2" placeholder="请再次输入新密码">
</div>
</div>
<div class="form-group clearfix">
<div class="col-sm-9 col-sm-offset-3">
<button type="submit" class="king-btn mr10 king-success">提交</button>
<button type="button" class="king-btn king-default ">取消</button>
</div>
</div>
</form>
编辑views.py的函数,增加业务逻辑。
def mopasswd(request):
if request.method == 'POST' and request.POST:
oldpassword = request.POST['oldpassword']
newpassword1 = request.POST['newpassword1']
newpassword2 = request.POST['newpassword2']
username = request.session['username']
userinfo = auth.authenticate(username=username, password=oldpassword)
if userinfo and newpassword1 == newpassword2:
user = User.objects.get(username=username)
user.set_password(newpassword2)
user.save()
return render(request, 'mopasswd.html')
return render(request,'mopasswd.html')
其中,用了auth.authenticate判断了当前用户名密码认证是否通过,以及newpassword1 == newpassword2判断了2次新密码是否相同,当上述两个条件都满足,就会修改密码。
修改完成后,注销然后重新登录,使用新密码登录,测试新密码是否能够成功修改。
但是其实当前的用户体验是非常不友好的,因为无论密码修改成功与否(可能有多种因素导致不成功),都没有任何提示,都是会刷新回返到修改用户密码界面。因此如果需要有反馈提示给用户修改失败,可以考虑两种方式:
1)直接在提交按钮或者用户名密码输入框下面,文字显示错误提示。例如两次输入的新密码不一致,或者密码不能为空。需要提前在提示未知预留一个标签,然后使用JavaScript来进行判断,然后根据不同的判断结果,进行不同的动作。
2)弹层:即在页面上面再弹一层对话框出来,提示错误情况。
下面针对两种方式的实现分开讲述。
2、JavaScript简介
JavaScript是一种脚本语言,与C语言、Python等一样有各种变量、if...else、for等语句,这里我们只针最常用的部分做一些介绍,更多详细的JavaScript教程,可参考W3School的教程:
2.1变量
JavaScrpit的变量,需要用var声明,并且语句要用分号结束
var username;
与CSS类似,可以用#或者.来获取HTML对象,其中:
$("#XXX")是匹配id="XXX"的元素
$(".XXX")是匹配class="XXX"的元素
$("#XXX").val()是id="XXX"的元素的值,这样就可以获取特定id的<input>标签的值了。
2.2函数
正常书写JavaScript函数,与其他语言一样,function(){},在花括弧里面编写内容。
function functionname(){
$("#button").click()
但是JavaScript函数内嵌在HTML页面里面的时候,写法不一样,要在外面包一层$()
$(
function functionname(){
$("#button").click()
2.3引用
2.3.1内嵌到HTML页面
JavaScript引用方式常用的有2种,一种是直接内嵌在HTML页面里面,在页面最下方编写,但是这种方式的JavaScript会在加载HTML页面的时候,自动执行一次。
在BASE02.html的</html>标签下面,添加如下代码。
<script>
function clicktest(){
$("#newpasswordinfo").text("这就是按下的效果")
</script>
然后修改mopasswd.py文件的“提交”按钮的type为button,然后增加onclick="clicktest()",表示当按下“提交”按钮,会执行该函数的动作。
<button type="button" class="king-btn mr10 king-success" onclick="clicktest()">提交</button>
刷新页面查看,但是发现直接就显示了“这就是按下的效果”,因为这种方式会在加载HTML页面的时候也执行JavaScript脚本。
2.3.2引用独立JS文件
另外一种方式是将函数写到JS文件里面,然后在HTML里面引用该文件。JS文件一般都会在/static/目录下建立一个JS文件夹,然后把JS脚本放在里面。而单独的JS文件写函数,就不需要用$()来引用了。
在/static/js/下新建一个stumgrtjs.js文件,编写如下代码:
function clicktest(){
$("#newpasswordinfo").text("这就是按下的效果")
在BASE02.html下面引用JS
<script type="text/javascript" src="/static/js/stumgrjs.js"></script>
重新刷新mopasswd页面,发现文字提示没有了。
修改mopasswd.py文件的“提交”按钮的type为button,然后增加onclick="clicktest()",表示当按下“提交”按钮,会执行该函数的动作。
<button type="button" class="king-btn mr10 king-success" onclick="clicktest()">提交</button>
点击“提交”按钮之后,文字出现。
这就是HTML独立引用JS文件,然后通过绑定按钮来调用JS函数。
3、JQuery
3.1引用jquery
JQuery是高度封装的JavaScript,用来与后台交互数据比较方便,使用需要像CSS一样进行引用。(也可以下载到本地,然后放入/static/js/文件夹进行本地引用。)下载地址:
我们在BASE页面里面加入JQuery引用,可以使用在线引用。
<script src="https://magicbox.bk.tencent.com/static_api/v3/assets/js/jquery-1.10.2.min.js"></script>
也可以使用本地引用,前提是先将文件下载到本地。
<script src="/static/js/jquery-1.10.2.min.js"></script>
3.2jquery的post请求
jquery的post请求格式如下:
$.post(url,{json格式的数据},function (条件) {
具体业务函数
},'返回的数据格式')
一般示例如下:
$.post('/changepassword/',{
'username':$('#username').val(),
'password':$('#password').val(),
},function (res) {
alert("添加成功!");
window.location.reload();
},'json')
/changepassword/为具体url,会到urls.py匹配具体的函数。
'username'等用了json格式组织数据,$('#username').val()为id='username'的输入框的具体数值。
post会将'username','password',通过post方法,将数据推送给/changepassword/对应的函数。
function里面的res,是接收/changepassword/对应的函数返回的数据,如果有数据返回,则会执行function里面的业务逻辑,如果没有任何数据返回,则不会执行function里面的业务逻辑。
最后面的'json'是指post使用怎样的格式将数据推送给/changepassword/对应的函数。
3.3jquery的ajax请求
ajax是jquery另外一种向后台推送数据的方法,格式如下:
$.ajax(
url:url,
type:"post",
data:{
beforeSend:function(){},
async:true,
success:function(){
error:function(){
一般示例如下:
$.ajax(
url:'/changepassword/',
type:"post",
data:{
'username':$('#username').val(),
'password':$('#password').val(),
beforeSend:function(){},
async:true,
success:function(res){
alert("添加成功!");
window.location.reload();
error:function(){
使用方法基本上与上面的post是一样的,不在赘述。
4、修改密码业务逻辑编写
首先由于前端现在改由JQuery来提交数据给后台,所以不用html的原生form来提交数据了,form里面有些东西需要修改。
<form class="form-horizontal" method="post">
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">原密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="oldpassword" id="oldpassword"
placeholder="请输入原密码">
</div>
</div>
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">新密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="newpassword1" id="newpassword1"
placeholder="请输入新密码">
</div>
</div>
<div class="form-group clearfix ">
<label class="col-sm-3 control-label bk-lh30 pt0">确认新密码:</label>
<div class="col-sm-9">
<input type="password" class="form-control bk-valign-top" name="newpassword2" id="newpassword2"
placeholder="请再次输入新密码">
<p class="help-block" id="newpasswordinfo"></p>
</div>
</div>
<div class="form-group clearfix">
<div class="col-sm-9 col-sm-offset-3">
<button type="button" class="king-btn mr10 king-success" onclick="changepassword()">提交</button>
<button type="button" class="king-btn king-default ">取消</button>
</div>
</div>
</form>
首先,由于JavaSript使用id与class来匹配元素而不是用name,所以每个<input>标签,需要增加id=""的属性。
其次,“提交”按钮的type要从submit修改回button,变回普通的按钮,然后onclick修改为调用一会儿stumgrtjs.js里面新增的changepassword()函数。
然后,编写stumgrtjs.js文件,里面增加changepassword()函数。
function changepassword() {
if ($('#oldpassword').val() == '' || $('#newpassword1').val() == '' || $('#newpassword2').val() == '') {
$("#newpasswordinfo").text("密码不能为空!");
} else if ($('#newpassword1').val() != $('#newpassword2').val()) {
$("#newpasswordinfo").text("两次输入的新密码不一致!");
} else {
$.post('/changepassword/', {
'oldpassword': $('#oldpassword').val(),
'newpassword1': $('#newpassword1').val(),
'newpassword2': $('#newpassword2').val(),
}, function (res) {
if(res.result){
alert("修改成功!");
window.location.reload();
}else{
alert("旧密码不正确,请重新输入!");
window.location.reload();
}, 'json')
核心业务逻辑为$.post(){}里面的内容,将oldpassword,newpassword1,2都推送给/changepassword/这个url对应的函数。(当然urls.py里面也要增加对应的路由,另外views.py里面也要增加对应的函数。)
urlpatterns = [
......
url(r'^changepassword/', changepassword),
]
function(res)检测是否有数值返回,if...else是根据返回的结果,判断修改是否成功,然后弹层提示告知用户。
前面一段if、else if、else分别是用来检测输入的<input>是否空值,2次新密码是否一致,不一致直接文件返回提示到预留的<p>标签。
前面我们都是把修改密码的业务逻辑直接写在views.py里面的mopasswd函数里面的,但是其实motchpasswd(修改老师用户密码)的业务逻辑是一样的,而且现在修改为用JQuery来提交数据了,因此可以直接把业务逻辑分离出来,单独用一个函数表示。那么上述mopasswd与motchpasswd两个页面都能复用这段代码。
def changepassword(request):
if request.method == 'POST' and request.POST:
oldpassword = request.POST['oldpassword']
newpassword2 = request.POST['newpassword2']
username = request.session['username']
userinfo = auth.authenticate(username=username, password=oldpassword)
if userinfo:
user = User.objects.get(username=username)
user.set_password(newpassword2)
user.save()
result = True