Ajax请求
1.1Ajax请求与get、post请求的区别
-
form请求:浏览器向网站发送请求时,url和表单的形式提交
- GET请求:url方式获取数据
- POST请求:以表单的形式提交数据
特点: 一次完整的GET或POST请求,会进行一次页面刷新
-
基于Ajax向后台发送请求(与post 一样偷偷发送请求)
- 依赖于jQuery
- 编写Ajax代码
$.ajax({ url: '/task/ajax', //请求地址 type: 'post',//请求类型(get) data: { //传送的数据 n1: 123, n2: 456, }, //后端返回的是带有数据结构的数据 //但是前端接收到的就是一个字符串,若想要获取到json格式的数据,需要加dataType dataType: 'JSON', success: function (res) { //执行成功的操作sussess(function定义success操作) //res 为json数据,带有数据结构 console.log(res); //接收视图函数task_ajax穿的数据res,并打印 })
success 操作。 表示执行成功获取后端的响应res之后的一系列操作
{
}
def task_ajax(request): print("get:", request.GET) print("post:", request.POST) dict = {'status': True, 'data': [1, 2, 3, 4]} # 将数据json.dumps()则返回带有数据结构的数据 return HttpResponse(json.dumps(dict)) # 返回{"status": true, "data": [1, 2, 3, 4]}
dict = {'status': True, 'data': [1, 2, 3, 4]}
return HttpResponse(dict)
返回statusdatareturn HttpResponse(json.dumps(dict))
返回{“status”: true, “data”: [1, 2, 3, 4]}
GET和POST每次请求需要刷新,而Ajax不需要刷新页面,因此使用Ajax请求,可以将增删改查集成在一个网页中
1.2 Ajax的绑定方式
1.2.1 点击函数绑定
<h3>测试1</h3>
<input type="button" class="btn btn-primary" value="点击" onclick="clickMe()">
function clickMe() {
//定义ajax
$.ajax({
url: '/task/ajax', //请求地址
type: 'post',//请求类型
data: { //传送的数据
n1: 123,
n2: 456,
},
success: function (res) { //执行成功的操作sussess(function定义success操作)
console.log(res); //接收视图函数task_ajax穿的数据res,并打印
}
})
}
onclick="clickMe()"
通过此属性,绑定此按钮通过点击此按钮,向
'/task/ajax'
传送数据,并获得响应res
1.2.2 借助jQuery绑定
- 页面框架加载完成自动执行的操作
$(function () { bindBtn1Event();//页面框架加载完成自动执行bindBtnEvent()函数 })
- jQuery相关知识点的应用
$('#id') 找到对应id的标签
$('.class') 找到对应class的标签
<h3>测试1</h3> <input id="btn1" type="button" class="btn btn-primary" value="点击">
<script> //方式2 利用jQuery方式绑定 id的方式绑定触发 //页面框架加载完成自动执行 $(function () { bindBtn1Event();//页面框架加载完成自动执行bindBtnEvent()函数 }) function bindBtn1Event() { //页面框架加载完成后,先找到id为btn1的位置,绑定点击执行某个操作 $('#btn1').click(function () { $.ajax({ url: '/task/ajax', //请求地址 type: 'post',//请求类型 data: { //传送的数据 n1: 123, n2: 456, }, //后端返回的是带有数据结构的数据 //但是前端接收到的就是一个字符串,若想要获取到json格式的数据,需要加dataType dataType: 'JSON', success: function (res) { //执行成功的操作sussess(function定义success操作) //res 为json数据,带有数据结构 console.log(res); //接收视图函数task_ajax穿的数据res,并打印 console.log(res.status); console.log(res.data); } }) }) } </script>
$('#btn1').click(function () {xxxx })
找到id=btn1的标签,点击后执行func函数一系列操作
1.2.3利用Ajax动态传输数据
- 传输较少数据
<h3>测试2</h3>
<input id="name" type="text" placeholder="姓名">
<input id="age" type="text" placeholder="年龄">
<input id="btn2" type="button" class="btn btn-primary" value="点击">
<script>
//方式2 利用jQuery方式绑定 id的方式绑定触发
//页面框架加载完成自动执行
$(function () {
bindBtn2Event();
})
function bindBtn2Event() {
//页面框架加载完成后,先找到id为btn3的位置,绑定点击执行某个操作
$('#btn2').click(function () {
$.ajax({
url: '/task/ajax', //请求地址
type: 'post',//请求类型
data: { //传送的数据
//利用$('#id').val()动态获取输入的数据
name: $('#name').val(),
age: $('#age').val(),
},
//后端返回的是带有数据结构的数据
//但是前端接收到的就是一个字符串,若想要获取到json格式的数据,需要加dataType
dataType: 'JSON',
success: function (res) { //执行成功的操作sussess(function定义success操作)
//res 为json数据,带有数据结构
console.log(res); //接收视图函数task_ajax穿的数据res,并打印
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
data: { //传送的数据 //利用$('#id').val()动态获取输入的数据 name: $('#name').val(), age: $('#age').val(), }
使用id得到对应的input输入框输入的数据
- 利用form传输多条数据
<h3>测试3</h3>
<form id="form3">
<input name="name" type="text" placeholder="姓名">
<input name="age" type="text" placeholder="年龄">
<input name="phone" type="text" placeholder="手机号">
<input name="wage" type="text" placeholder="工资">
<input name="more" type="text" placeholder="更多">
<input id="btn3" type="button" class="btn btn-primary" value="点击">
</form>
<script>
//方式2 利用jQuery方式绑定 id的方式绑定触发
//页面框架加载完成自动执行
$(function () {
bindBtn2Event();
})
function bindBtn3Event() {
//页面框架加载完成后,先找到id为btn3的位置,绑定点击执行某个操作
$('#btn3').click(function () {
$.ajax({
url: '/task/ajax', //请求地址
type: 'post',//请求类型
data: $('#form3').serialize(), //自动获取表单中所有输入框的数据(返回字典)
//后端返回的是带有数据结构的数据
//但是前端接收到的就是一个字符串,若想要获取到json格式的数据,需要加dataType
dataType: 'JSON',
success: function (res) { //执行成功的操作sussess(function定义success操作)
//res 为json数据,带有数据结构
console.log(res); //接收视图函数task_ajax穿的数据res,并打印
console.log(res.status);
console.log(res.data);
}
})
})
}
</script>
data: $('#form3').serialize(), //自动获取表单中所有输入框的数据(返回字典)
1.2 Ajax实现任务列表功能
1.2.1 构造表
class Task(models.Model):
"""任务"""
title = models.CharField(max_length=64,verbose_name="标题")
detail = models.TextField(verbose_name="详细信息")
level_choice = (
(1,'紧急'),
(2,'重要'),
(3,'一般'),
)
level = models.SmallIntegerField(verbose_name='级别',choices=level_choice, default=1)
user = models.ForeignKey(verbose_name="负责人",to='Admin',on_delete=models.CASCADE)
1.2.2 任务展示列表
task_list.html
{% extends 'layout.html' %}
{% block content %}
<h1>Ajax案例</h1>
<div class="panel panel-default">
<div class="panel-heading">任务列表</div>
...
...
...
<div class="bs-example" data-example-id="hoverable-table">
<table class="table table-hover">
<thead>
<tr>
<th>ID</th>
<th>标题</th>
<th>详细信息</th>
<th>等级</th>
<th>负责人</th>
</tr>
</thead>
<tbody>
{% for obj in queryset %}
<tr>
<td>{{ obj.id }}</td>
<td>{{ obj.title }}</td>
<td>{{ obj.detail }}</td>
<td>{{ obj.get_level_display }}</td>
<td>{{ obj.user }}</td>
</div>
{% endblock %}
...
...
{% block js %}
{% endblock %}
由于负责人为外键,数据展示时显示为对象,应在Admin表中让其默认返回username
class Admin(models.Model):
"""管理员表"""
username = models.CharField(max_length=32, verbose_name="用户名")
password = models.CharField(max_length=64, verbose_name="密码")
def __str__(self):
return self.username
task.py
def task_list(request):
form = TaskModelForm()
queryset = models.Task.objects.all()
return render(request, 'task_list.html', {"queryset": queryset, "form": form})
1.3 Ajax实现任务添加功能
task_list
{% extends 'layout.html' %}
{% block content %}
<h1>Ajax案例</h1>
<div class="panel panel-default">
<div class="panel-heading">任务列表</div>
<div class="panel-body">
<div class="bs-example" data-example-id="simple-form-inline">
<form class="form" id="formAdd" novalidate>
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span class="error_msg" style="color: red;"></span>
</div>
{% endfor %}
<input id="btnAdd" type="button" class="btn btn-success" value="提交">
</form>
</div>
</div>
....
....
....
{% endblock %}
{% block js %}
<script>
$(function () {
bindBtnAddEvent();
})
function bindBtnAddEvent() {
//页面框架加载完成后,先找到id为btnAdd的位置,绑定点击执行某个操作
$('#btnAdd').click(function () {
//每次填写前先把错信息清空
$('.error_msg').empty()
$.ajax({
url: '/task/add', //请求地址
type: 'post',//请求类型
data: $('#formAdd').serialize(), //自动获取表单中所有输入框的数据(返回字典)
//后端返回的是带有数据结构的数据
//但是前端接收到的就是一个字符串,若想要获取到json格式的数据,需要加dataType
dataType: 'JSON',
success: function (res) {
if (res.status){
alert("添加成功")
}else {
// res.errors = {'title': ['这个字段是必填项。'], 'detail': ['这个字段是必填项。'], 'user': ['这个字段是必填项。']}
//遍历错误信息字典
$.each(res.errors,function (name,data){
console.log(name,data)
$('#id_'+name).next().text(data[0]);
})
}
}
})
})
}
</script>
{% endblock %}
task.py
@csrf_exempt
def task_add(request):
form = TaskModelForm(request.POST)
if form.is_valid():
form.save()
# Ajax无需刷新,因此不用跳转页面
# 成功直接向前端传一个成功响应即可
data_dict = {'status': True}
return HttpResponse(json.dumps(data_dict))
# 失败,将错误信息向前端传输
data_dict = {'status': False, 'errors': form.errors}
print(data_dict)
return HttpResponse(json.dumps(data_dict,ensure_ascii=False))
- 要点1
@csrf_exempt
接收ajax传来的post请求,需免除csrf_token验证
- 要点2
data_dict = {'status': True} return HttpResponse(json.dumps(data_dict))
Ajax无需刷新,因此不用跳转页面,成功直接向前端传一个成功响应即可(此响应传输到中)
data_dict = {'status': False, 'errors': form.errors} return HttpResponse(json.dumps(data_dict,ensure_ascii=False))
若校验失败,将错误信息响应给Ajax的success中的res参数,便于前端显示
- 要点3
success: function (res) { if (res.status){ alert("添加成功") }else { } //遍历错误信息字典 $.each(res.errors,function (name,data){ $('#id_'+name).next().text(data[0]); }) } }
res.errors = {'title': ['这个字段是必填项。'], 'detail': ['这个字段是必填项。'], 'user': ['这个字段是必填项。']
$.each(res.errors,function (name,data){ $('#id_'+name).next().text(data[0]); })
$.each()
jQuery的遍历函数
$('#id_'+name).next().text(data[0]);
表示将id为id_name的标签(form在生成input输入框时,默认id为id_name)的文本显示为错误列表第一条错误
- 要点4
$('.error_msg').empty()
<span class="error_msg" style="color: red;"></span>
错误显示后,在下次Ajax请求后清除,避免校验成功还显示失败时的提示