转载自:https://code.ziqiangxuetang.com/django/django-ajax.html
Django Ajax
有时候我们需要在不刷新的情况下载入一些内容,在网页的基本知识中我们介绍了 ajax 技术。
在本文中讲解如何用 Django 来实现 不刷新网页的情况下加载一些内容。
由于用 jQuery 实现 ajax 比较简单,所以我们用 jQuery库来实现,想用原生的 javascript 的同学可以参考:ajax 教程,下面也有例子提供下载。
本节有多个实例提供下载,通过看代码可以更快的学习。
第一节
这里用 Django 表单 第一节 中的一个例子,我们要实现的是在不刷新的情况下显示计算结果到页面上。
修改 index.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
|
<!DOCTYPE html>
<
html
>
<
body
>
<
p
>请输入两个数字</
p
>
<
form
action
=
"/add/"
method
=
"get"
>
a: <
input
type
=
"text"
id
=
"a"
name
=
"a"
> <
br
>
b: <
input
type
=
"text"
id
=
"b"
name
=
"b"
> <
br
>
<
p
>result: <
span
id
=
'result'
></
span
></
p
>
<
button
type
=
"button"
id
=
'sum'
>提交</
button
>
</
form
>
<
script
src
=
"http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"
></
script
>
<
script
>
$(document).ready(function(){
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val();
$.get("/add/",{'a':a,'b':b}, function(ret){
$('#result').html(ret)
})
});
});
</
script
>
</
body
>
</
html
>
|
在原来的基础上,在一些元素上加了 id, 以便于获取值和绑定数据,然后我们用了jQuery.get() 方法,并用 $(selector).html() 方法将结果显示在页面上,如下图:
备注:关于请求头和 request.is_ajax() 方法使用
views.py 中可以用 request.is_ajax() 方法判断是否是 ajax 请求,需要添加一个 HTTP 请求头:
原生javascript:
1
|
xmlhttp.setRequestHeader(
"X-Requested-With"
,
"XMLHttpRequest"
);
|
用 jQuery:
1
|
用 $.ajax 方法代替 $.get,因为 $.get 在 IE 中不会发送 ajax header
|
服务器端会将请求头的值全部大写,中划线改成下划线,并在非标准的头前面加上 HTTP_,这个过程可以认为相当于以下Python代码:
1
2
3
4
5
6
7
8
9
|
STANDARD_HEADERS
=
[
'REFER'
,
'HOST'
, ...]
# just for example
def
handle_header(value):
value
=
value.replace(
'-'
,
'_'
).upper()
if
value
in
STANDARD_HEADERS:
return
value
return
'HTTP_'
+
value
|
第二节
更复杂的例子,传递一个数组或字典到网页,由JS处理,再显示出来。
views.py
1
2
3
4
5
6
7
8
9
10
|
from
django.http
import
HttpResponse
import
json
def
ajax_list(request):
a
=
range
(
100
)
return
HttpResponse(json.dumps(a), content_type
=
'application/json'
)
def
ajax_dict(request):
name_dict
=
{
'twz'
:
'Love python and Django'
,
'zqxt'
:
'I am teaching Django'
}
return
HttpResponse(json.dumps(name_dict), content_type
=
'application/json'
)
|
Django 1.7 及以后的版本有更简单的方法(使用 JsonResponse(官方文档)):
1
2
3
4
5
6
7
8
9
|
from
django.http
import
JsonResponse
def
ajax_list(request):
a
=
range
(
100
)
return
JsonResponse(a, safe
=
False
)
def
ajax_dict(request):
name_dict
=
{
'twz'
:
'Love python and Django'
,
'zqxt'
:
'I am teaching Django'
}
return
JsonResponse(name_dict)
|
在 django 1.6 及以前的旧版本中可以自己写一个 JsonResponse 方法,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from
django.http
import
HttpResponse
import
json
class
JsonResponse(HttpResponse):
def
__init__(
self
,
content
=
{},
mimetype
=
None
,
status
=
None
,
content_type
=
'application/json'
):
super
(JsonResponse,
self
).__init__(
json.dumps(content),
mimetype
=
mimetype,
status
=
status,
content_type
=
content_type)
|
写好后,我们在 urls.py 中添加以下两行:
1
2
|
url(r
'^ajax_list/$'
,
'tools.views.ajax_list'
, name
=
'ajax-list'
),
url(r
'^ajax_dict/$'
,
'tools.views.ajax_dict'
, name
=
'ajax-dict'
),
|
打开开发服务器 python manage.py runserver
我们访问对应的网址会看到输出值:
下一步就是在无刷新的情况下把内容加载到网页了,我们修改一下首页的模板 index.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
44
45
46
47
48
49
50
51
52
53
54
55
|
<!DOCTYPE html>
<
html
>
<
body
>
<
p
>请输入两个数字</
p
>
<
form
action
=
"/add/"
method
=
"get"
>
a: <
input
type
=
"text"
id
=
"a"
name
=
"a"
> <
br
>
b: <
input
type
=
"text"
id
=
"b"
name
=
"b"
> <
br
>
<
p
>result: <
span
id
=
'result'
></
span
></
p
>
<
button
type
=
"button"
id
=
'sum'
>提交</
button
>
</
form
>
<
div
id
=
"dict"
>Ajax 加载字典</
div
>
<
p
id
=
"dict_result"
></
p
>
<
div
id
=
"list"
>Ajax 加载列表</
div
>
<
p
id
=
"list_result"
></
p
>
<
script
src
=
"http://apps.bdimg.com/libs/jquery/1.11.1/jquery.min.js"
></
script
>
<
script
>
$(document).ready(function(){
// 求和 a + b
$("#sum").click(function(){
var a = $("#a").val();
var b = $("#b").val();
$.get("/add/",{'a':a,'b':b}, function(ret){
$('#result').html(ret);
})
});
// 列表 list
$('#list').click(function(){
$.getJSON('/ajax_list/',function(ret){
//返回值 ret 在这里是一个列表
for (var i = ret.length - 1; i >= 0; i--) {
// 把 ret 的每一项显示在网页上
$('#list_result').append(' ' + ret[i])
};
})
})
// 字典 dict
$('#dict').click(function(){
$.getJSON('/ajax_dict/',function(ret){
//返回值 ret 在这里是一个字典
$('#dict_result').append(ret.twz + '<
br
>');
// 也可以用 ret['twz']
})
})
});
</
script
>
</
body
>
</
html
>
|
技能提升:getJSON中的写的对应网址,用 urls.py 中的 name 来获取是一个更好的方法!
标签:{% url 'name' %}
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
|
<script>
$(document).ready(
function
(){
// 求和 a + b
$(
"#sum"
).click(
function
(){
var
a = $(
"#a"
).val();
var
b = $(
"#b"
).val();
$.get(
"{% url 'add' %}"
,{
'a'
:a,
'b'
:b},
function
(ret){
$(
'#result'
).html(ret);
})
});
// 列表 list
$(
'#list'
).click(
function
(){
$.getJSON(
"{% url 'ajax-list' %}"
,
function
(ret){
//返回值 ret 在这里是一个列表
for
(
var
i = ret.length - 1; i >= 0; i--) {
// 把 ret 的每一项显示在网页上
$(
'#list_result'
).append(
' '
+ ret[i])
};
})
})
// 字典 dict
$(
'#dict'
).click(
function
(){
$.getJSON(
"{% url 'ajax-dict' %}"
,
function
(ret){
//返回值 ret 在这里是一个字典
$(
'#dict_result'
).append(ret.twz +
'<br>'
);
// 也可以用 ret['twz']
})
})
});
</script>
|
这样做最大的好处就是在修改 urls.py 中的网址后,不用改模板中对应的网址。
补充:如果是一个复杂的 列表 或 字典,因为比如如下信息:
1
2
3
4
5
|
person_info_dict
=
[
{
"name"
:
"xiaoming"
,
"age"
:
20
},
{
"name"
:
"tuweizhong"
,
"age"
:
24
},
{
"name"
:
"xiaoli"
,
"age"
:
33
},
]
|
这样我们遍历列表的时候,每次遍历得到一个字典,再用字典的方法去处理,当然有更简单的遍历方法:
用 $.each() 方法代替 for 循环,html 代码(jQuery)
1
2
3
4
5
|
$.getJSON(
'ajax-url-to-json'
,
function
(ret) {
$.each(ret,
function
(i,item){
// i 为索引,item为遍历值
});
});
|
补充:如果 ret 是一个字典,$.each 的参数有所不同,详见:http://api.jquery.com/jquery.each/
1
2
3
4
5
|
$.getJSON(
'ajax-get-a-dict'
,
function
(ret) {
$.each(ret,
function
(key, value){
// key 为字典的 key,value 为对应的值
});
});
|
最后,附上一个返回图片并显示的ajax实例: