什么是Ajax?

以往我们对后端提交数据时,会造成我们的页面刷新或跳转,如何不刷新页面也能更新当前页面的数据呢?这时我们就可以使用Ajax技术来实现。

Ajax这个术语源自描述从基于 Web 的应用到基于数据的应用。Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
使用 JavaScript 向服务器提出请求并处理响应而不阻塞用户核心对象XMLHttpRequest。通过这个对象,您的 JavaScript 可在不重载页面的情况与 Web 服务器交换数据,即在不需要刷新页面的情况下,就可以产生局部刷新的效果。

Demo1 发送GET请求

base.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
56
57
58
59
60
61
62
63
64
65
66
67
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>OPS System</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1-dist/css/bootstrap.css' %}">
<style>
.navbar {
border-radius: 0;
}
</style>
{% block css %}

{% endblock %}

{% block js %}

{% endblock %}
</head>
<body>

<nav class="navbar navbar-default">
<div class="container">
<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="#">Manager System</a>
</div>

<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="/task/list/">Task</a></li>
</ul>

<ul class="nav navbar-nav navbar-right">
{# <li><a href="/admin/login/">Login</a></li>#}
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">{{ request.session.info.name }}<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">User info</a></li>
<li><a href="#">Manager</a></li>
<li><a href="/admin/logout/">Logout</a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>

{% block content %}

{% endblock %}

<script src="{% static 'js/jquery-3.6.0.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
{% block js_foot %}

{% endblock %}
</body>
</html>

task_list.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
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>task list</h1>
<h3>ex1</h3>
<input type="button" class="btn btn-primary" value="click" onclick="clickMe();">
</div>
{% endblock %}
{% block js_foot %}
<script type="text/javascript">
function clickMe() {
$.ajax({
url: '/task/ajax/',
type: "get",
data: {
n1: 123,
n2: 345,
},
success: function (res) {
console.log(res);
}
})
}
</script>
{% endblock %}

views.py代码部分样例

1
2
3
4
5
6
def task_list(request):
""" task list """
return render(request,"taks_list.html")

def task_ajax(request):
return HttpResponse('successsssssss')

urls.py代码部分样例

1
2
3
4
5
urlpatterns = [
# path('admin/', admin.site.urls),
path('task/list/', views.task_list),
path('task/ajax/', views.task_ajax),
]

测试Ajax请求

Demo2 发送POST请求

demo1示例是一个get请求,在这里我们创建一个post方式,改为post方式后,Django会报一个csrftoken错误,以前我们页面会加上csrftoken,但是ajax默认这里并不会带上csrftoken(可以从header取,方式复杂),所以我们可以加上在视图函数上加上@csrf_exempt来忽略

views.py部分代码样例

1
2
3
4
5
6
7
8
9
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def task_ajax(request):
if request.method == "GET":
print(request.GET)
return HttpResponse('Get successsssssss')
if request.method == "POST":
print(request.POST)
return HttpResponse('Post successsssssss')

task_list.html部分代码样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{% block js_foot %}
<script type="text/javascript">
function clickMe() {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
success: function (res) {
console.log(res);
}
})
}
</script>
{% endblock %}

测试输出

1
2
[17/Jul/2022 05:59:32] "POST /task/ajax/ HTTP/1.1" 200 19
<QueryDict: {'n1': ['123'], 'n2': ['345']}>

调整task_list.html使用Jquery绑定事件

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
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>task list</h1>
<h3>ex1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="click">
</div>

{% endblock %}
{% block js_foot %}
<script type="text/javascript">
$(function () {
bindBtn1Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}

Demo3 前端接收Json对象

views.py部分代码样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt
def task_ajax(request):
if request.method == "GET":
print(request.GET)
return HttpResponse('Get successsssssss')
if request.method == "POST":
print(request.POST)
data = {
"path": request.path_info,
"method": request.method,
}
return HttpResponse(json.dumps(data))

task_lsit.html部分代码样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{% block js_foot %}
<script type="text/javascript">
$(function () {
bindBtn1Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}

访问测试

Deno4 传输Json对象至后端

views.py部分代码样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt
def task_ajax(request):
if request.method == "GET":
print(request.GET)
return HttpResponse('Get successsssssss')
if request.method == "POST":
print(request.POST)
data = {
"path": request.path_info,
"method": request.method,
"data": request.POST
}
return HttpResponse(json.dumps(data))

task_list代码样例

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
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>task list</h1>
<h3>ex1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="click">

<h3>ex2</h3>
<input type="text" id="txtName" placeholder="name">
<input type="text" id="txtAge" placeholder="age">
<input id="btn2" type="button" class="btn btn-primary" value="click">
</div>

{% endblock %}
{% block js_foot %}
<script type="text/javascript">
$(function () {
bindBtn1Event();
bindBtn2Event();
})

function bindBtn1Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtName").val(),
age: $("#txtAge").val(),
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
function bindBtn2Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}

测试访问

Demo5 使用Jquery serialize方法自动解析表单字段

taks_list.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h1>task list</h1>
<h3>ex1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="click">

<h3>ex2</h3>
<input type="text" id="txtName" placeholder="name">
<input type="text" id="txtAge" placeholder="age">
<input id="btn2" type="button" class="btn btn-primary" value="click">

<h3>ex3</h3>

{# 1.form需要定义id #}
{# 2.input框需要定义name属性 #}
<form id="userinfo">
<input type="text" name="name" placeholder="name">
<input type="text" name="age" placeholder="age">
<input type="email" name="email" placeholder="email">
<input type="text" name="more" placeholder="more">
<input id="btn3" type="button" class="btn btn-primary" value="click">
</form>
</div>

{% endblock %}
{% block js_foot %}
<script type="text/javascript">
$(function () {
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
})

function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}

function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtName").val(),
age: $("#txtAge").val(),
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}

function bindBtn3Event() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#userinfo").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
</script>
{% endblock %}

测试访问

Demo6 渲染后端校验错误的信息

task_list.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{% extends 'base.html' %}
{% block content %}
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">Task</div>
<div class="panel-body">
<form id="taskinfo">
{% for field in obj %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span class="error-msg text-danger"></span>
</div>
{% endfor %}
<button id="btn4" type="button" class="btn btn-primary">提交</button>
</form>

</div>
</div>
<br>
<h1>task list</h1>
<h3>ex1</h3>
<input id="btn1" type="button" class="btn btn-primary" value="click">

<h3>ex2</h3>
<input type="text" id="txtName" placeholder="name">
<input type="text" id="txtAge" placeholder="age">
<input id="btn2" type="button" class="btn btn-primary" value="click">

<h3>ex3</h3>
{# #}
<form id="userinfo">
<input type="text" name="name" placeholder="name">
<input type="text" name="age" placeholder="age">
<input type="email" name="email" placeholder="email">
<input type="text" name="more" placeholder="more">
<input id="btn3" type="button" class="btn btn-primary" value="click">
</form>
</div>
{% endblock %}
{% block js_foot %}
<script type="text/javascript">
$(function () {
bindBtn1Event();
bindBtn2Event();
bindBtn3Event();
bindBtn4Event();
})
function bindBtn1Event() {
$("#btn1").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
n1: 123,
n2: 345,
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
function bindBtn2Event() {
$("#btn2").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: {
name: $("#txtName").val(),
age: $("#txtAge").val(),
},
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
function bindBtn3Event() {
$("#btn3").click(function () {
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#userinfo").serialize(),
dataType: "JSON",
success: function (res) {
console.log(res);
}
})
})
}
function bindBtn4Event() {
$("#btn4").click(function () {

{# 每次提交时先清空错误信息,避免错误提示一直存在 #}
$(".error-msg").empty();
$.ajax({
url: '/task/ajax/',
type: "post",
data: $("#taskinfo").serialize(),
dataType: "JSON",
success: function (res) {
if (res.status){
alert("success");
} else {
console.log(res);
$.each(res.errors, function (name,data) {
{# django form表单渲染时会为每个字段设置id,值为id+字段label名#}
$("#id_" + name).next().text(data[0]);
})
}
}
})
})
}
</script>
{% endblock %}

models.py部分代码样例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Admin(models.Model):
def __str__(self):
return self.username
username = models.CharField(verbose_name="username",max_length=32)
password = models.CharField(verbose_name="password",max_length=64)

class Task(models.Model):
""" task """
level_choice = (
(1, "紧急"),
(2, "重要"),
(3, "临时"),
)
level = models.SmallIntegerField(verbose_name="级别", choices=level_choice, default=3)
title = models.CharField(verbose_name="标题", max_length=64)
detail = models.TextField(verbose_name="详细信息")
user = models.ForeignKey(verbose_name="负责人",to="Admin",on_delete=models.CASCADE)

views.py部分代码样例

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
import json

from django.forms.utils import ErrorDict
from django.views.decorators.csrf import csrf_exempt

from app01.models import Task

@csrf_exempt
def task_ajax(request):
""" task ajax """
if request.method == "GET":
print(request.GET)
return HttpResponse('Get successsssssss')
if request.method == "POST":
print(request.POST)
# data = {
# "path": request.path_info,
# "method": request.method,
# "data": request.POST
# }
form = TaskModelForm(data=request.POST)
if form.is_valid():
form.save()
data = {"status": True,}
return HttpResponse(json.dumps(data))
# print(form.errors.as_json())
data = {"status": False, "errors": form.errors}
return HttpResponse(json.dumps(data, ensure_ascii=False))

def task_list(request):
""" task list """
form = TaskModelForm()
context = {'obj': form}
return render(request, "task_list.html", context)

测试访问