目录
一、Ajax 介绍
Ajax是一种异步提交,就是在当前页面时,不刷新当前页面的前提下,将数据提交到另一个页面
Ajax可以局部刷新页面,在一个页面下,不整体刷新页面,而是可以将当前页面的某一个部分刷新
此处回忆一下同步异步/阻塞非阻塞
同步异步:描述的任务的提交方式
同步:提交任务之后 原地等待任务的返回结果 期间不干日他的事情
异步::提交任务之后 不原地等待 直接执行下一行代码 任务结果的返回通过回调机制
阻塞非阻塞:程序的运行状态------了解程序运行的状态图
Ajax(Asynchronous Javascript And XML):翻译成中文就是“异步的 Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
Ajax不是新的编程语言,而是一种使用现有标准的新方法
Ajax是一门 JS 技术,基于原生 JS 开发,但用原生的 JS 写代码太过于繁琐,我们用 JavaSquery是实现
提示:JavaSquery是基于javascript方法封装的。。。。
Ajax最大的优点:不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
二、Ajax 实例
展示一个前端页面 ,页面有三个输入框,一个提交按钮,前面两个输入框输入内容,点击按钮,同过Ajax实现点击按钮向后端提交数据,实现将前两个输入框中的数据计算和返回给第三个输入框中显示
# add_num.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <title>Title</title> </head> <body> <input id="i1" type="text">+<input id="i2" type="text">=<input id="i3" type="text"> <button>Ajax提交</button> <script> {#1.先找到button这个对象,绑定点击事件#} $('button').click(function () { {#2. 触发ajax事件#} $.ajax({ {#1. url:用来控制提交数据的地址,不写默认的是当前的地址#} url:'', {#2. type:用来控制向地址提交的请求,可以小写#} type:'post', {#3. 用来向后端提交的数据#} data:{num1:$('#i1').val(),num2:$('#i2').val()}, {#4. 接收从后端返回的数据,也就是异步返回的结果#} success:function(data){ {#将结果给第三个输入框#} $('#i3').val(data) } }) }) </script> </body> </html>
# views.py文件 def add_num(request): # 判断是否为Ajax请求 if request.is_ajax(): if request.method == 'POST': num1 = request.POST.get('num1') num2 = request.POST.get('num2') data = int(num1)+int(num2) print(data) return HttpResponse(data) return render(request,'add_num.html')
# url.py文件 from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 通过Ajax向后端传数据将结果计算返回 url(r'^add/$',views.add_num,name='add_page'), ]
三、contentType 交互的数据格式
我们知道form表单,默认的向后端提交数据的编码格式是urlencoded
urlencoded:
()=()&()=()
这种就是符合urlencoded数据格式
- django后端针对
()=()&()=()
的urlencoded数据格式会自动解析,将结果打包给request.POST 用户只需要从request.POST即可获取对应信息
formdata:
- django后端针对formdata格式类型数据 也会自动解析,但是不会方法request.POST中而是给你放到了request.FILES中
ajax默认的提交数据的编码格式也是urlencoded
总结: django后端针对不同的编码格式数据 会有不同的处理机制以及不同的获取该数据的方法
四、Ajax传json格式数据
注意:在前后端进行数据交互的时候,一定要表名所发的是什么数据,是什么格式的,并且一定要遵守,表明是什么格式数据,就一定要发与之对应的数据格式。
django后端针对前端页面发送过来的 json 数据不会自动解析,会直接原封不动的给你放到request.body中,需要你手动处理,获取数据
# json.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <title>Title</title> </head> <body> <input id="i1" type="text"> <input id="i1" type="text"> <button>提交</button> <script> $('button').click(function () { $.ajax({ url:'', type:'post', data:JSON.stringify({'name':'cecilia','pwd':'123'}), contentType:'application/json', success:function (data) { alert(data) } }) }) </script> </body> </html>
#views.py文件 import json def up_json(request): if request.is_ajax(): if request.method == 'POST': json_bytes = request.body json_str = json_bytes.decode('utf8') json_dic = json.loads(json_str) print(json_dic,type(json_dic)) return render(request,'json.html')
注意:当前端向后端发送的数据不是json格式的时候,django是默认不给看request.body中的内容的,一定要牢记,当前端向后端发送json格式数据的时候,所有的数据信息都是保存在request.body中的
在上图中可以看到,我们已经在前端页面中表明了我发的是json格式的数据,所以他提交的数据已经不在是向get和post的请求的那种()=()&()=()的形式了,所以在post自然是获取不到任何数据的了
如上图,我们点击view score的时候,我们可以看到浏览器也默认用application/json的形式来接收前端发送的数据的
五、Ajax向后端传文件
Ajax向后端传文件,需要用到内置对象Formdata
,该对象既可以传普通的键值,也可以传文件
# upload_file.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <title>Title</title> </head> <body> <input type="text" name="username" id="t1"> <input type="text" name="password" id="t2"> <input type="file" name="myfile" id="t3">上传文件 <button>提交</button> <Script> $('button').click(function () { // 1.先生成一个formdata对象 var myFormData = new FormData(); // 2.朝对象中添加普通的键值 myFormData.append('username',$("#t1").val()); myFormData.append('password',$("#t2").val()); // 3.朝对象中添加文件数据 // 1.先通过jquery查找到该标签 // 2.将jquery对象转换成原生的js对象 // 3.利用原生js对象的方法 直接获取文件内容 myFormData.append('myfile',$('#t3')[0].files[0]); $.ajax({ url:'', type:'post', data:myFormData, // 直接丢对象 // ajax传文件 一定要指定两个关键性的参数 contentType:false, // 不用任何编码 因为formdata对象自带编码 django能够识别该对象 processData:false, // 告诉浏览器不要处理我的数据 直接发就行 success:function (data) { alert(data) } }) }) </Script> </body> </html>
# views.py文件 def upload_file(request): # 判断请求是否为Ajax请求 if request.is_ajax(): if request.method == 'POST': print(request.POST) # 这里只是收到了普通的键值对 print(request.FILES) # 上传的文件的对象在这里 return HttpResponse('收到') return render(request,'upload_file.html')
注意:
利用formdata对象 能够简单的快速传输数据 (普通键值 + 文件)
有几个参数
data:formdata # 对象 contentType:false # 不用任何编码 因为formdata对象自带编码 django能够识 processData:false # 告诉浏览器不要处理我的数据 直接发就行
六、给前端返回一个字典
将用户表的数据 查询出来 返回给前端
给前端的是一个大字典 字典里面的数据的一个个的字段
# dict.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <title>Title</title> </head> <body> {{user_list}} {#这是最原始的利用模板语法来接收的大字典#} {#{% for user_obj in user_list %}#} {# <p>username:{{ user_obj.username }} age: {{ user_obj.age }} gender: {{ user_obj.gender }}</p>#} {#{% endfor %}#} </body> </html>
# views.py文件 from app01 import models from django.core import serializers def back_dic(request): user_obj_list = models.UserInfo.objects.all() # 1.原始的方式向前端页面传送字典 # user_list = [] # for user_obj in user_obj_list: # user_list.append({ # 'username':user_obj.username, # 'age':user_obj.age, # 'gender':user_obj.get_gender_display() # }) # 2. 利用serializers这个模块来帮我们很简单的将对象变为字典 ''' serializers:模块有两个参数 1.format:代表序列成什么格式的数据 2.queryset:要序列化的对象 ''' user_list = serializers.serialize('json',user_obj_list) return render(request,'dict.html',locals())
七、Ajax + sweetalert
# sweet.html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {% load static %} <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script> <link rel="stylesheet" href="{% static 'sweetalert/dist/sweetalert.css' %}"> <script src="{% static 'sweetalert/dist/sweetalert.js' %}"></script> <meta name="viewport" content="width=device-width, initial-scale=1 "> <title>Title</title> </head> <body> <div class="container-fluid"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2>数据展示</h2> <table class="table table-bordered table-hover table-striped"> <thead> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>性别</td> <td class="text-center">编辑</td> </tr> </thead> <tbody> {% for user_obj in user_obj_list %} <tr> <td>{{forloop.counter }}</td> <td>{{user_obj.username }}</td> <td>{{user_obj.age}}</td> <td>{{user_obj.get_gender_display}}</td> <td> <a href="#" class="btn btn-success">编辑</a> <a href="#" class="btn btn-warning cancel" del_id="{{ user_obj.pk }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> $('.cancel').click(function () { var $btn = $(this); swal({ title: "你确定要删吗?", text: "你要是删了,你就准备好跑路吧!", type: "warning", showCancelButton: true, //这是确定俺就 confirmButtonClass: "btn-danger", confirmButtonText: "对,老子就要删!", //确定按钮的文本 cancelButtonText: "算了,算了!", //这是取消删除的文本内容 closeOnConfirm: false, showLoaderOnConfirm: true//实现确定按钮后的加载后删除 }, function(){ $.ajax({ url:'', type:'post', data:{'delete_id':$btn.attr('delete_id')}, success:function (data) { if (data.code){ swal(data.msg, "你可以回去收拾行李跑路了.", "success"); // 1.直接刷新页面 {#window.location.reload()#} // 2.通过DOM操作 实时删除 $btn.parent().parent().remove() }else{ swal("发生了未知错误!", "我也不知道哪里错了.", "info"); } } }); }); }) </script> </body> </html>
# views.py文件 import time from django.http import JsonResponse def sweetalert(request): # 如果是get请求,就把用户对象返回给前端页面 user_obj_list = models.UserInfo.objects.all() # 如果是POST请求,就删除需要删除的用户对象 if request.method == 'POST': # 先定义一个字典,作为返回给前端页面的 back_dic = {"code":True,'msg':''} delete_id = request.POST.get('delete_id') models.UserInfo.objects.filter(pk=delete_id).delete() back_dic['msg'] = '后端传来的:真的被我删了' time.sleep(3)# 这里是实现一个加载一段时间后删除 return JsonResponse(back_dic) return render(request,'sweet.html',locals())