67-django-前后端传数据编码格式、ajax传json格式数据、ajax传文件数据、ajax与sweetalert结合二次确认、django自带的序列化组件、批量插入、分页器
今日内容概要
- 前后端传输数据的编码格式(contentType)
- ajax发送json格式数据
- ajax发送文件数据
- ajax结合sweetalert实现删除按钮的二次确认
- django自带的序列化组件(drf做铺垫)
- 批量插入
- 自己写一个分页器(只需要掌握分页器的推导思路即可)
- 自定义分页器的使用(简单几行代码即可 需要掌握)
今日内容详细
前后端传输数据的编码格式(contentType)
1 # 我们主要研究post请求数据的编码格式 2 """ 3 get请求数据就是直接放在url后面的 4 url?username=jason&password=123 5 """ 6 7 # 可以朝后端发送post请求的方式 8 """ 9 1.form表单 10 2.ajax请求 11 """ 12 13 14 """ 15 前后端传输数据的编码格式 16 urlencoded 17 18 formdata 19 20 json 21 """ 22 # 研究form表单 23 默认的数据编码格式是urlencoded 24 数据格式:username=jason&password=123 25 django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中 26 username=jason&password=123 >>> request.POST 27 28 如果你把编码格式改成formdata,那么针对普通的键值对还是解析到request.POST中而将文件解析到request.FILES中 29 30 form表单是没有办法发送json格式数据的 31 32 33 # 研究ajax 34 默认的编码格式也是urlencoded 35 数据格式:username=jason&age=20 36 django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中 37 username=jason&age=20 >>> request.POST
ajax发送json格式数据
1 """ 2 前后端传输数据的时候一定要确保编码格式跟数据真正的格式是一致的 3 不要骗人家!!! 4 5 {"username":"jason","age":25} 6 在request.POST里面肯定找不到 7 8 django针对json格式的数据 不会做任何的处理 9 10 request对象方法补充 11 request.is_ajax() 12 判断当前请求是否是ajax请求 返回布尔值 13 14 """ 15 16 <script> 17 $('#d1').click(function () { 18 $.ajax({ 19 url:'', 20 type:'post', 21 data:JSON.stringify({'username':'jason','age':25}), 22 contentType:'application/json', // 指定编码格式 23 success:function () { 24 25 } 26 }) 27 }) 28 </script> 29 30 json_bytes = request.body # 获取浏览器发送过来的原生的二进制数据 31 json_str = json_bytes.decode('utf-8') 32 json_dict = json.loads(json_str) 33 34 # json.loads括号内如果传入了一个二进制格式的数据那么内部自动解码再反序列化 35 json_dict = json.loads(json_bytes) 36 37 """ 38 ajax发送json格式数据需要注意点 39 1.contentType参数指定成:application/json 40 2.数据是真正的json格式数据 41 3.django后端不会帮你处理json格式数据需要你自己去request.body获取并处理 42 """
ajax发送文件
1 """ 2 ajax发送文件需要借助于js内置对象FormData 3 4 """ 5 <script> 6 // 点击按钮朝后端发送普通键值对和文件数据 7 $('#d4').on('click',function () { 8 // 1 需要先利用FormData内置对象 9 let formDateObj = new FormData(); 10 // 2 添加普通的键值对 11 formDateObj.append('username',$('#d1').val()); 12 formDateObj.append('password',$('#d2').val()); 13 // 3 添加文件对象 14 formDateObj.append('myfile',$('#d3')[0].files[0]) 15 // 4 将对象基于ajax发送给后端 16 $.ajax({ 17 url:'', 18 type:'post', 19 data:formDateObj, // 直接将对象放在data后面即可 20 21 // ajax发送文件必须要指定的两个参数 22 contentType:false, // 不需使用任何编码 django后端能够自动识别formdata对象 23 processData:false, // 告诉你的浏览器不要对你的数据进行任何处理 24 25 success:function (args) { 26 } 27 }) 28 29 30 }) 31 </script> 32 33 def ab_file(request): 34 if request.is_ajax(): 35 if request.method == 'POST': 36 print(request.POST) 37 print(request.FILES) 38 return render(request,'ab_file.html') 39 40 """ 41 总结: 42 1.需要利用内置对象FormData 43 // 2 添加普通的键值对 44 formDateObj.append('username',$('#d1').val()); 45 formDateObj.append('password',$('#d2').val()); 46 // 3 添加文件对象 47 formDateObj.append('myfile',$('#d3')[0].files[0]) 48 2.需要指定两个关键性的参数 49 contentType:false, // 不需使用任何编码 django后端能够自动识别formdata对象 50 processData:false, // 告诉你的浏览器不要对你的数据进行任何处理 51 3.django后端能够直接识别到formdata对象并且能够将内部的普通键值自动解析并封装到request.POST中 文件数据自动解析并封装到request.FILES中 52 """
django自带的序列化组件(前后端分离)(drf做铺垫)
1 """ 2 如果发现你可以直接使用MySQL但是无法使用sqlite3 3 不要慌张不要恐惧 你只需要按照之前MySQL的操作将sqlite3的驱动装一下即可 4 """ 5 # 需求:在前端给我获取到后端用户表里面所有的数据 并且要是列表套字典 6 import json 7 from django.http import JsonResponse 8 from django.core import serializers 9 def ab_ser(request): 10 user_queryset = models.User.objects.all() 11 # [{},{},{},{},{}] 12 # user_list = [] 13 # for user_obj in user_queryset: 14 # tmp = { 15 # 'pk':user_obj.pk, 16 # 'username':user_obj.username, 17 # 'age':user_obj.age, 18 # 'gender':user_obj.get_gender_display() 19 # } 20 # user_list.append(tmp) 21 # return JsonResponse(user_list,safe=False) 22 # return render(request,'ab_ser.html',locals()) 23 24 # 序列化 25 res = serializers.serialize('json',user_queryset) 26 """会自动帮你将数据变成json格式的字符串 并且内部非常的全面""" 27 return HttpResponse(res) 28 """ 29 [ 30 {"pk": 1, "username": "jason", "age": 25, "gender": "male"}, 31 {"pk": 2, "username": "egon", "age": 31, "gender": "female"}, 32 {"pk": 3, "username": "kevin", "age": 32, "gender": "others"}, 33 {"pk": 4, "username": "tank", "age": 40, "gender": 4} 34 ] 35 前后端分离的项目 36 作为后端开发的你只需要写代码将数据处理好 37 能够序列化返回给前端即可 38 再写一个接口文档 告诉前端每个字段代表的意思即可 39 40 41 [ 42 { "model": "app01.user", 43 "pk": 1, 44 "fields": {"username": "jason", "age": 25, "gender": 1}}, 45 46 { "model": "app01.user", 47 "pk": 2, 48 "fields": {"username": "egon", "age": 31, "gender": 2}}, 49 50 { "model": "app01.user", 51 "pk": 3, 52 "fields": {"username": "kevin", "age": 32, "gender": 3}}, 53 54 { "model": "app01.user", 55 "pk": 4, 56 "fields": {"username": "tank", "age": 40, "gender": 4}} 57 ] 58 写接口就是利用序列化组件渲染数据然后写一个接口文档 该交代交代一下就完事 59 """
ajax结合sweetalert
1 """ 2 要学会如何拷贝 3 学会基于别人的基础之上做修改 4 研究各个参数表示的意思 然后找葫芦画瓢 5 """ 6 <script> 7 $('.del').on('click',function () { 8 // 先将当前标签对象存储起来 9 let currentBtn = $(this); 10 // 二次确认弹框 11 swal({ 12 title: "你确定要删吗?", 13 text: "你可要考虑清除哦,可能需要拎包跑路哦!", 14 type: "warning", 15 showCancelButton: true, 16 confirmButtonClass: "btn-danger", 17 confirmButtonText: "是的,老子就要删!", 18 cancelButtonText: "算了,算了!", 19 closeOnConfirm: false, 20 closeOnCancel: false, 21 showLoaderOnConfirm: true #删除延时 22 }, 23 function(isConfirm) { 24 if (isConfirm) { 25 // 朝后端发送ajax请求删除数据之后 再弹下面的提示框 26 $.ajax({ 27 {#url:'/delete/user/' + currentBtn.attr('delete_id'), // 1 传递主键值方式1#} 28 url:'/delete/user/', // 2 放在请求体里面 29 type:'post', 30 data:{'delete_id':currentBtn.attr('delete_id')}, 31 success:function (args) { // args = {'code':'','msg':''} 32 // 判断响应状态码 然后做不同的处理 33 if(args.code === 1000){ 34 swal("删了!", args.msg, "success"); 35 // 1.lowb版本 直接刷新当前页面 36 {#window.location.reload()#} 37 // 2.利用DOM操作 动态刷新 38 currentBtn.parent().parent().remove() 39 }else{ 40 swal('完了','出现了位置的错误','info') 41 } 42 } 43 44 }) 45 46 } else { 47 swal("怂逼", "不要说我认识你", "error"); 48 } 49 }); 50 }) 51 52 </script> 53 54 55 56 import time 57 from django.http import JsonResponse 58 def delete_user(request): 59 """ 60 前后端在用ajax进行交互的时候 后端通常给ajax的回调函数返回一个字典格式的数据 61 :param request: 62 :return: 63 """ 64 if request.is_ajax(): 65 if request.method == 'POST': 66 back_dic = {"code":1000,'msg':''} 67 time.sleep(3) # 模拟操作数据的延迟 68 delete_id = request.POST.get('delete_id') 69 models.User.objects.filter(pk=delete_id).delete() 70 back_dic['msg'] = '数据已经删了,你赶紧跑路!' 71 # 我们需要告诉前端我们操作的结果 72 return JsonResponse(back_dic)
批量插入
1 def ab_pl(request): 2 # 先给Book插入一万条数据 3 # for i in range(10000): 4 # models.Book.objects.create(title='第%s本书'%i) 5 # # 再将所有的数据查询并展示到前端页面 6 book_queryset = models.Book.objects.all() 7 8 # 批量插入 9 # book_list = [] 10 # for i in range(100000): 11 # book_obj = models.Book(title='第%s本书'%i) 12 # book_list.append(book_obj) 13 # models.Book.objects.bulk_create(book_list) 14 """ 15 当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间 16 :param request: 17 :return: 18 """ 19 return render(request,'ab_pl.html',locals())
分页器
1 """ 2 总数据100 每页展示10 需要10 3 总数据101 每页展示10 需要11 4 总数据99 每页展示10 需要10 5 6 如何通过代码动态的计算出到底需要多少页? 7 8 9 在制作页码个数的时候 一般情况下都是奇数个 符合中国人对称美的标准 10 """ 11 # 分页 12 book_list = models.Book.objects.all() 13 14 # 想访问哪一页 15 current_page = request.GET.get('page',1) # 如果获取不到当前页码 就展示第一页 16 # 数据类型转换 17 try: 18 current_page = int(current_page) 19 except Exception: 20 current_page = 1 21 # 每页展示多少条 22 per_page_num = 10 23 # 起始位置 24 start_page = (current_page - 1) * per_page_num 25 # 终止位置 26 end_page = current_page * per_page_num 27 28 # 计算出到底需要多少页 29 all_count = book_list.count() 30 31 page_count, more = divmod(all_count, per_page_num) 32 if more: 33 page_count += 1 34 35 page_html = '' 36 xxx = current_page 37 if current_page < 6: 38 current_page = 6 39 for i in range(current_page-5,current_page+6): 40 if xxx == i: 41 page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i) 42 else: 43 page_html += '<li><a href="?page=%s">%s</a></li>'%(i,i) 44 45 46 47 book_queryset = book_list[start_page:end_page] 48 49 """ 50 django中有自带的分页器模块 但是书写起来很麻烦并且功能太简单 51 所以我们自己想法和设法的写自定义分页器 52 53 上述推导代码你无需掌握 只需要知道内部逻辑即可 54 55 我们基于上述的思路 已经封装好了我们自己的自定义分页器 56 之后需要使用直接拷贝即可 57 """
今日测验
""" 今日考题 1.默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数 2.什么是序列化,截止目前为止你所接触过的序列化有哪些 3.批量插入数据需要注意什么,orm批量插入数据的语法? 4.当需要展示的数据量特别多的情况下,会采取什么优化措施,你能否简要描述一下该措施的实施思路,以及该措施具体应用下的操作步骤 5.简述面相对象的三大特性及特点,其中你认为哪个特性使用频率最高,为什么 """
今日内容回顾
前后端数据交互编码方式(contentType)
1 """ 2 前后端传输数据编码格式你只需要在知道下面三种即可 3 urlencoded 4 5 formdata 6 7 application/json 8 """ 9 # get请求无需研究 10 11 # 针对form表单 12 默认是urlencoded 13 数据格式:username=jason&password=123 14 django后端针对符合urlencoded编码格式的数据,会自动帮你解析并封装到request.POST中 15 16 form表单可以通过enctype来修改编码方式>>>:formdata 17 form表单即可以发送普通键值也可以发送文件 18 django后端针对formdata编码格式的数据,会自动将普通键值对还是解析到request.POST,将文件自动解析到request.FILES里面 19 20 form表单是无法发送json格式的数据的 21 22 23 # ajax 24 默认是urlencoded 25 数据格式:username=jason&password=123 26 django后端针对符合urlencoded编码格式的数据,会自动帮你解析并封装到request.POST中
ajax发送json格式数据
1 """ 2 不同程序/应用之间进行数据交互的时候 一定要确保数据格式和编码一致 3 不要欺骗别人!!! 4 """ 5 $.ajax({ 6 url:'', 7 type:'', 8 data:JSON.stringify({'username':'jason','password':123}), 9 dataType:'JSON', 10 contentType:'application/json', 11 success:function(args){} 12 }) 13 # 注意:django后端针对json格式的数据不会做任何的处理,你需要自己去request.body中获取原生的二进制数据自己处理 14 """ 15 1.解码 16 2.反序列化 17 18 (json.loads能够自动先解码再反序列化) 19 """
ajax发送文件
1 """ 2 ajax发送文件需要借助于内置对象FormData 会非常的方便 3 """ 4 let formDataObj = new FormData(); # 既可以加普通键值也可以加文件 5 formDataObj.append('username','jason') 6 formDataObj.append('myfile',$('#i1')[0].files[0]) 7 $.ajax({ 8 url:'', 9 type:'', 10 data:formDataObj, 11 dataType:'JSON', 12 13 # 两个关键性的参数 14 contentType:false, 15 processData:false, 16 17 success:function(args){} 18 }) 19 # 注意:django后端能够自动识别formdata对象 并且也能够将对象里面包含的普通键值对自己解析并封装到request.POST里面 将文件自动解析封装到request.FILES 20 21 """ 22 request对象方法补充 23 request.is_ajax() 24 """
django内置的序列化组件
1 """ 2 到了工作中之后 大部分的项目都是前后端分离的 3 也就意味着我们可能无法直接使用django提供的模版语法来实现前后端数据交互 4 5 所以这个时候我们需要将数据处理成大家公共的都能处理的格式(json格式) 6 一般情况下都是处理成列表套字典的形式[{},{}] 7 8 由于针对数据的封装有时候会非常的繁琐 所以有现成的模块可以直接完成 9 1.django内置的模块 10 2.第三方模块:django restframework 11 """ 12 from django.core import serializers 13 user_queryset = models.User.objects.all() 14 res = serializers.serialize('json',user_queryset) # json格式字符串 15 return HttpResponse(res) 16 """ 17 [ 18 { 19 "models":"app01.user", 20 "pk":1, 21 "fields":{ 22 "username":"jason", 23 ... 24 } 25 }, 26 {}, 27 {}, 28 ] 29 """
ajax结合sweetalert实现二次确认
1 """ 2 我们在工作中写项目的时候其实也是一样的 3 就是先找现成的模块 代码拷贝过来然后二次修改 4 当你在一家公司呆了很久,那么这家的业务逻辑基本你都掌握了 5 """ 6 # sweetalert针对中文可能会出现展示补全的现象 7 自己找到对应的标签书写css修改样式即可 8 9 # 你也可以不结合sweetalert就用ajax和BOM操作也能完成二次确认 10 res = confirm() 11 if(res){ 12 $.ajax({}) 13 }else{ 14 不发 15 }
批量插入
1 """ 2 当频繁的走数据库操作的时候 效率会呈现指数型下降 3 """ 4 user_list = [] 5 for i in range(100000): 6 user_list.append(models.User(title='%s'%i)) 7 models.User.objects.bulk_create(user_list)
自定义分页器
1 """ 2 django也有内置的分页器模块 但是功能较少代码繁琐不便于使用 3 所以我们自己自定义我们自己的分页器 4 """ 5 1.queryset对象是直接切片操作的 6 2.用户到底要访问哪一页 如何确定? url?page=1 7 current_page = request.GET.get('page',1) 8 # 获取到的数据都是字符串类型 你需要注意类型转换 9 3.自己规定每页展示多少条数据 10 per_page_num = 10 11 4.切片的起始位置和终止位置 12 start_page = (current_page - 1)* per_page_num 13 end_page = current_page * per_page_num 14 # 利用简单找规律 找出上述四个参数的规律 15 5.当前数据的总条数 16 book_queryset.count() 17 6.如何确定总共需要多少页才能展示完所有的数据 18 # 利用python内置函数divmod() 19 page_count, more = divmod(all_count,per_page_num) 20 if more: 21 page_count += 1 22 7.前端模版语法是没有range功能的 23 # 前端代码不一定非要在前端书写 也可以在后端生成传递给页面 24 8.针对需要展示的页码需要你自己规划好到底展示多少个页码 25 # 一般情况下页码的个数设计都是奇数(符合审美标准) 11个页码 26 当前页减5 27 当前页加6 28 你可以给标签价样式从而让选中的页码高亮显示 29 9.针对页码小于6的情况 你需要做处理 不能再减 30 31 自定义分页器推导到第九部就可以 无需你继续推到了 代码也无需掌握
作业
""" 必做 1.整理今日内容到博客 2.熟练掌握ajax发送json数据和文件数据代码 3.自己完成按钮的二次确认操作(ajax+sweetalert) 4.尝试理解自定义分页器逻辑,自己推导出简易版本代码 选做 1.阅读博客,预习自定义分页器封装版本使用方式 """
"""我们在工作中写项目的时候其实也是一样的就是先找现成的模块 代码拷贝过来然后二次修改当你在一家公司呆了很久,那么这家的业务逻辑基本你都掌握了"""# sweetalert针对中文可能会出现展示补全的现象自己找到对应的标签书写css修改样式即可
# 你也可以不结合sweetalert就用ajax和BOM操作也能完成二次确认res = confirm() if(res){ $.ajax({}) }else{ 不发 }————————————————版权声明:本文为CSDN博主「学技术的城」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/wg14747421417/article/details/106546397