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格式的数据,需要加dataTypedataType: '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格式的数据,需要加dataTypedataType: '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格式的数据,需要加dataTypedataType: '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格式的数据,需要加dataTypedataType: '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格式的数据,需要加dataTypedataType: '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请求后清除,避免校验成功还显示失败时的提示