Django+Ajax实现局部刷新

背景说明

Django == 3.2.12
Python == 3.8.1

这次的目标就是:在页面输入一个应用名,然后不用提交按钮,直接就动态刷新出来这个应用在数据库的情况。同时可以通过下拉单selectcheckbox来调整该应用的状态,这样达到界面化查询和修改数据的目的:

关键html代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<div class="card-body">
<input class="form-control form-control-lg" type="text" placeholder="请输入应用名" id="app">
<br>
<div class="form-group row" id="get-status"></div>
<br>
<div class="form-group">
<label>应用等级</label>
<select class="form-control" id="app_level">
<option>核心</option>
<option>非核心</option>
</select>
</div>
<div class="form-group">
<label>是否接入测试平台</label>
<select class="form-control" id="test_platform">
<option>True</option>
<option>False</option>
</select>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="fuwuhua" id="fuwuhua" name="hangye">
<label class="form-check-label">服务化</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="guojihangye" id="guojihangye" name="hangye">
<label class="form-check-label">国际行业</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="maochaohangye" id="maochaohangye" name="hangye">
<label class="form-check-label">猫超行业</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="fchangye" id="fchangye" name="hangye">
<label class="form-check-label">FC行业</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="pingtaihangye" id="pingtaihangye" name="hangye">
<label class="form-check-label">平台行业</label>
</div>
</div>
<div class="card-footer">
<input type="button" class="btn btn-danger float-right" id="submit" value="提交">
</div>

这个get-status标签是用来ajax动态展示数据库查询结果的,而提交button会再提交一次ajax把数据给后台views.py

失去焦点

要实现”输入应用名后,实时刷新后台数据”,那么就需要判断失去焦点,这个方法在ajax的方法如下:

1
2
3
4
5
6
7
8
9
<script>
// 失去焦点
$("#app").blur(function() {
var app = $("#app").val();
console.log("BYEBYE Russia!");
console.log(app);

});
</script>

这里就是判断app标签一旦鼠标离开,那就会触发这个方法—-在控制台里输入字符串。效果如下:

checkbox传值

组件checkbox的传值跟input不太一样,它不是想象中的“打勾了就是true,不打勾就是false”这样的判断逻辑。在这个case里,我先给每一个checkbox统一的name,然后轮询来得到他们各自的value。方法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<script>
$(document).ready(function(){
$('#submit').click(function(){
var app = $("#app").val();
var app_level = $("#app_level").val();
var test_platform = $("#test_platform").val();
var hangye = $("input[name='hangye']:checked").serialize(); //这里获取所有的name是hangye的标签

$.ajax({
cache: false,
type: "POST", //方法类型
dataType: "json", //预期服务器返回的数据类型
url: '{% url "change_app_level_ajax" %}' , //传给后面的url
data: {
app: app,
app_level: app_level,
test_platform: test_platform,
hangye: hangye //这里将以上的值传给后端views.py的值
},
traditional: true,
async: false,

success: function (data) {
if(data.status == "success"){
alert("提交成功!")
location.reload(); // 直接刷新当前页面
}
},
error: function() {
alert("申请提交失败!")
}
});
});
})
</script>

这里将app,app_level,test_platformhangye作为一个json传给Django的views.py。那么在views.py里的change_app_level_ajax就这么写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from urllib.parse import parse_qs	# 这里引入parse_qs

def change_app_level_ajax(request):
if request.method == "POST":
app = request.POST.get("app", None) # 从json里获取目标应用
app_level = request.POST.get("app_level", None)
test_platform = request.POST.get("test_platform", False)
hangye = parse_qs(request.POST.get("hangye", False)) # 这里按照&拆开,拆成了字典{'hangye': ['XXX', 'XXX', 'XXX']}

print(app, app_level, test_platform, hangye['hangye'])


return JsonResponse({'status': 'success'}) # 返回成功信息给ajax
else:
return JsonResponse({'status': 'error'}) # 失败

为什么这里要有一个parse_qs?因为这里的hangye得到的样式是hangye=AAA&hangye=BBB&hangye=CCC的样子,那么通过parse_qs方法,可以给它优雅的拆成一个dict:{'hangye': ['AAA', 'BBB', 'CCC']},然后就是可以对这个字典进一步的加工了。

ajax局部刷新页面

搭配submit或者上面的“失去焦点”,可以触发ajax,将获取到的前端数据给到后端,然后后端处理它。但是为了更加友好的交互,我们就要达到页面的局部刷新,这种刷新方法也很简单。

首先先需要在前端里确认一个标签,比如最上面代码的<div class="form-group row" id="get-status"></div>,这个标签就是将来刷新的地方。

然后就是在ajax的方法最后,说明在get-status进行替换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<script>
// 失去焦点
$("#app").blur(function() {
var app = $("#app").val();
console.log("BYEBYE Russia!");
console.log(app);

$.ajax({
type: "POST", //提交方式
dataType: "json", //数据类型
url: '{% url "get_info_ajax" %}', //请求url
data: {
app: app //这里将以上的值传给后端views.py的值
},

success: function (data) {
if(data.status == "success"){
$("#get-status").html("该应用目前的状态是:" + data.app_info); // 这个data是一个字典,传递的是data的app.info字段
}
if(data.status == "noexist"){
$("#get-status").html("此应用不存在在数据库里!");
}
},
error: function() {
alert("申请提交失败!请联系管理员查看问题。")
}
});
});
</script>

这样只要后台views.py返回的是success的话,get-status的标签变成该应用目前的状态是:" + data.app_info。如果返回的是noexist,get-status的标签变成此应用不存在在数据库里!。效果如图:

参考资料

http://www.chendacheng.com/content/?category=Django%E4%B8%93%E9%A2%98&article=Django_07.html
https://blog.csdn.net/weixin_44144510/article/details/121995683
https://zhuanlan.zhihu.com/p/25016726
https://blog.csdn.net/sinat_36553913/article/details/78418098

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------