Django Ajax
Ajax
1 大坑 如果在form表单中,写button和input是submit类型,会触发form表单的提交 如果不想触发 不写在form表单里面 将input的type写成button 2 大坑 后端响应格式如果是:html/text格式,ajax接收到的数据后需要自己转成对象 总结:后端返回数据,统一都用JsonResponse 3 大坑 如果使用了ajax,后端就不要返回rediret,render,HttpResponse 直接返回JsonResponse
""" 异步提交:请求发出去 不会卡在这里,可以干其他事情 局部刷新:js的DOM操作 使页面内局部刷新 基本上很多web页面都有很多ajax请求 例子:github注册 动态获取用户名,实时跟后端确认,并实时展示到前端(局部刷新) 朝后端发送请求的方式 1、浏览器地址栏直接输入url回车 GET请求 2、a标签href属性 GET请求 3、form表单 GET请求/POST请求 4、ajax GET请求/POST请求 AJAX 不是新的编程语言,而是一种使用现有标准的新方法。 就类似于装饰器 基于现有的知识点拼凑出来的 AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程) AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求; 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。 Ajax只学习jQuery封装之后的版本(不学原生的 原生的复杂并且在实际项目中也一般不用) 所以我们在前端页面使用ajax的时候需要确保导入了jQuery ps:并不只有jQuery能够实现ajax,其他框架也可以,但是换汤不换药 原理是一样的 """
Ajax基本语法
""" $.ajax({ url:'', # 朝后端哪个地址发送 跟action三种书写方式一致 (不写 写全称 写后缀) type:'get/post', # 提交方式 默认get 跟form表单method参数一致 data:{'uauername':'jason','password':123}, # 要发送的数据 success:function(args(形参 写啥都可以){ # 异步回调处理机制 } }) """ 当你在利用ajax进行前后端交互的时候 后端无论返回什么都只会被回调函数接收 而不再影响这个浏览器页面了 # 扩展 参数 代码发布项目还会涉及 dataType:'JSON' """ 当后端是以HttpResponse返回的json格式的数据 默认是不会自动反序列化的 1、自己手动JSON.parse() 2、配置dataType参数 """ # 结论: 写ajax的时候 你可以直接将dataType参数加上,以防万一 或者后端就用JsonResonse $.ajax({ url:'', # 朝后端哪个地址发送 跟action三种书写方式一致 (不写 写全称 写后缀) type:'get/post', # 提交方式 默认get 跟form表单method参数一致 dataType:'JSON', data:{'uauername':'jason','password':123}, # 要发送的数据 success:function(args(形参 写啥都可以){ # 异步回调处理机制 } })
小例子
""" 页面上有三个input框 在前两个框中输入数字 点击按钮 朝后端发送ajax请求 后端计算出结果 再返回给前端 动态展示到第三个input框中 (整个过程页面不准有刷新 也不能在前端计算) """ <script> // 先给按钮绑定一个点击事件 $('#btn').click(function () { // 朝后端发送ajax请求 $.ajax({ // 1、指定朝哪个后端发送ajax请求 url:'', // 不写就是朝当前地址提交 // 2、请求方式 type:'post', // 不指定默认就是get 都是小写 // 3、数据 {#data:{'username':'jason','password':123},#} {#data:{'i1':$('#d1').val(),'i2':$('#d2').val()},#} // 4、回调函数(异步回调机制):当后端给你返回结果的时候会自动触发 args接收后端的返回结果 success:function (args) { {#alert(args) // 通过DOM操作动态渲染到第三个input框里面#} {#$('#d3').val(args)#} console.log(typeof args) } }) }) </script> """ 针对后如果是用HttpResponse返回的数据 回调函数不会自动帮你反序列化 如果后端直接用的是JsonResponse返回的数据 回调函数会自动帮你反序列化 HttpResponse解决方式 1、自己在前端利用JSON.parse() 2、在ajax里面配置一个参数 后面再讲 """
前后端传输数据的编码格式(contentType)
# 我们主要研究post请求数据的编码格式 """ get请求数据就是直接放在url后面的 url?username=jason&password=123 """ # 可以朝后端发送post请求的方式 """ 1、form表单 2、ajax请求 """ """ 前后端传输数据的编码格式 urlencode:默认的 ---> 从request.POST取提交的数据 formdata:上传文件的 ---> 从request.POST取提交的数据 json:ajax发送json格式数据 ---> request.POST取不出数据了 使用ajax和form表单 默认都是urlencoded格式 """ # 研究form表单 默认的数据编码格式是urlencoded 数据格式:username=jason&password=123 """ django后端针对 符合 urlencoded编码格式的数据 都 会自动帮你解析封装到requet.POST中 """ 如果把编码格式改为formdata,那么针对普通的键值对还是解析到request.POST中 而将文件解析到request.FILES中 form表单是没有办法发送json格式的数据的 # 研究ajax 默认的编码格式也是urlencoded 数据格式:username=jason&age=20 """ django后端针对 符合 urlencoded编码格式的数据 都 会自动帮你解析封装到requet.POST中 """
ajax发送json格式数据
""" 前后端传输数据的时候 一定要确保编码格式跟数据真正的格式是一致的 不要骗人家!!! {"username":"jason","age":25} 在request.POST里面肯定找不到 django针对json request对象方法补充 request.is_ajax() 判断当前请求是否是ajax请求 返回布尔值 """ # 前端: <script> $('#d1').click(function () { $.ajax({ url:'', type:'post', data:JSON.stringify({'username':'jason','age':25}), contentType:'application/json', // 指定编码格式 success:function () { } }) }) </script> # 后端 # ajax发送json格式数据 import json def ab_json(request): if request.is_ajax(): print(request.POST) print(request.FILES) print(request.is_ajax()) print(request.body) # b'{"username":"jason","age":25}' # 针对json格式数据需要你自己手动处理 json_bytes = request.body # json_str = json_bytes.decode('utf-8') # json_dict = json.loads(json_str) # print(json_dict,type(json_dict)) # {'username': 'jason', 'age': 25} <class 'dict'> # json.loads括号内如果传入了一个二进制格式的数据 # 那么内部可以自动解码再反序列化 json_dict = json.loads(json_bytes) print(json_dict,type(json_dict)) return render(request,'ab_json.html') """ ajax发送json格式数据需要注意点 1、contentType参数指定成:application/json 2、数据是真正的json格式数据 3、django后端不会帮你处理json格式数据需要你自己去requset.body获取并处理 """
ajax发送文件
""" ajax发送文件需要借助于js内置对象FormData """ # 前端 <body> <p>username:<input type="text" id="d1"></p> <p>password:<input type="password" id="d2"></p> <p><input type="file" id="d3"></p> <button class="btn btn-info" id="d4">点我</button> <script> // 点击按钮朝后端发送普通键值对 和文件数据 $('#d4').on('click',function () { // 1、需要先利用FormData内置对象 let formDataObj = new FormData(); // 2、添加普通的键值对 formDataObj.append('username',$('#d1').val()) formDataObj.append('password',$('#d2').val()) // 3、添加文件对象 formDataObj.append('myfile',$('#d3')[0].files[0]) // 4、将对象基于ajax发送给后端 $.ajax({ url:'', type:'post', data:formDataObj, //直接将对象放在data后面即可 // ajax发送文件必须要指定的两个参数 contentType:false, // 不需要使用如何编码 django后端能够自动识别formdata对象 processData:false, // 告诉你的浏览器不要对你的数据进行任何处理 success:function (args){ } }) }) </script> </body> # 后端 # ajax发送文件 def ab_file(request): if request.is_ajax(): if request.method == 'POST': print(request.POST) print(request.FILES) return render(request,'ab_file.html') """ 总结: 1、需要利用内置对象FormData // 2、添加普通的键值对 formDataObj.append('username',$('#d1').val()) formDataObj.append('password',$('#d2').val()) // 3、添加文件对象 formDataObj.append('myfile',$('#d3')[0].files[0]) 2、需要指定两个关键性的参数 contentType:false, // 不需要使用如何编码 django后端能够自动识别formdata对象 processData:false, // 告诉你的浏览器不要对你的数据进行任何处理 3、django后端能够直接识别到formdata对象并且能够 将内部的普通键值自动解析并封装到request.POST中 将内部的文件数据自动解析并封装到request.FILES中 """
django自带的序列化组件(drf做铺垫)
""" 如果发现你可以直接使用MySQL但是无法使用sqlite3 不要慌张不要恐惧 你只需要按照之前MySQL的操作将sqlite3的驱动装一下即可 """ # 需求:在前端给我获取到后端用户表里面所有的数据 并且要是列表套字典 # 序列化组件相关 from app01 import models import json from django.http import JsonResponse from django.core import serializers def ab_ser(request): user_queryset = models.User.objects.all() # [{},{},{},{}] # user_list = [] # for user_obj in user_queryset: # tmp = { # 'pk':user_obj.pk, # 'username':user_obj.username, # 'age':user_obj.age, # 'gender':user_obj.get_gender_display() # } # user_list.append(tmp) # return JsonResponse(user_list,safe=False) # return render(request,'ab_ser.html',locals()) """ [{"pk": 1, "username": "jason", "age": "25", "gender": "male"}, {"pk": 2, "username": "egon", "age": "31", "gender": "female"}, {"pk": 3, "username": "keven", "age": "32", "gender": "others"}, {"pk": 4, "username": "tank", "age": "40", "gender": 4} ] 前后端分离的项目 作为后端开发的你只需要写代码将数据处理好 能够序列化返回给前端即可 再写一个接口文档 告诉前端每个字段代表的意思即可 """ # 序列化 res = serializers.serialize('json',user_queryset) """ 会自动帮你把数据变成json格式的字符串 并且内部非常的全面 不好用 字段不能控制 目前阶段 要做序列化 for循环拼列表套字典 """ return HttpResponse(res) """ [{"model": "app01.user", "pk": 1, "fields": {"username": "jason", "age": "25", "gender": 1}}, {"model": "app01.user", "pk": 2, "fields": {"username": "egon", "age": "31", "gender": 2}}, {"model": "app01.user", "pk": 3, "fields": {"username": "keven", "age": "32", "gender": 3}}, {"model": "app01.user", "pk": 4, "fields": {"username": "tank", "age": "40", "gender": 4}}] """ """ 写接口 就是利用序列化组件渲染数据 然后写一个接口文档 该交代的交代一下就完事了 """
ajax结合sweetalert实现删除按钮的二次确认操作
""" sweetalert网址: https://lipis.github.io/bootstrap-sweetalert/ """ """ 自己要学会如何拷贝 学会基于别人的基础之上做修改 研究各个参数表示的意思 然后照葫芦画瓢 """ <script> $('.del').on('click',function () { // 先将当前标签对象存储起来 let currentBtn = $(this); // 二次确认弹框 swal({ title: "你确定要删除吗", text: "你可要考虑清除哦,可能需要拎包跑路哦", type: "warning", showCancelButton: true, confirmButtonClass: "btn-danger", confirmButtonText: "是的,老子就要删!", cancelButtonText: "算了,算了!!!", closeOnConfirm: false, closeOnCancel: false, showLoaderOnConfirm: true }, function(isConfirm) { if (isConfirm) { // 朝后端发送ajax请求删除数据之后 再弹下面的提示框 $.ajax({ {#url:'/delete/user/' + currentBtn.attr('delete_id'), // 传递主键值方式1#} url:'/delete/user/', //2 放在请求体里面 type: 'post', data:{'delete_id':currentBtn.attr('delete_id')}, success:function (args) { //args = {'code':'','msg':''} //判断响应状态码 然后做不同的处理 if(args.code == 1000){ swal('删了',args.msg,'success'); // 1、lowb版本 直接刷新当前页面 {#window.location.reload();#} // 2、利用DOM操作 动态刷新 currentBtn.parent().parent().remove() }else{ swal('完了','出现了未知的错误','info'); } } }) swal("删除了!", "赶紧跑路叭", "success"); } else { swal("怂比", "不要说我认识你", "error"); } }); }) </script>
页面器
""" django中有自带的分页器模块 但是书写起来很麻烦并且功能太简单 所以我们自己想发设发的写自定义分页器 https://www.cnblogs.com/Dominic-Ji/articles/12035722.html """