zoukankan      html  css  js  c++  java
  • day67——前后端传输数据的编码格式、ajax传json数据/传文件、批量插入

    前后端传输数据的编码方式(contentType)

    get请求数据会在url后面用?拼接,我们不做研究,主要研究post请求的编码格式。

    可以朝后端发请求的方式:

    • 浏览器地址栏输入url回车(GET/POST请求)

    • a便签的href属性(GET)

    • form表单(GET/POST请求)

      ​ 默认是GET请求method='get'

      ​ 修改method='post'朝后端发送的是post请求

    • ajax(GET/POST请求)

      ​ 默认是GET请求type='get'

      ​ 修改type='post'发送post请求

    前后端传输数据的三种编码格式:

    • urlencoded
    • formdata
    • json

    form表单传输数据的编码方式:

    默认编码格式:urlencoded

    数据格式:username=tom&password=111,跟get请求url问号后携带数据的格式相同

    AJAX传输数据的编码方式:

    默认编码格式:urlencoded

    数据格式:username=tom&password=111

    结论:django后端会将urlencoded编码格式的数据都封装解析到request.POST中,如果手动的将form表单的编码格式换成formdata,那么普通的数据还是封装进request.POST内,不同的是针对文件类型的数据会被解析封装到request.FILES中;form表单无法发送json格式数据。

    AJAX发送json格式数据

    不同程序/应用之间进行数据交互的时候 一定要确保数据格式和编码一致;以json为传输的编码格式(contentType:'application/json')那么数据就必须是json格式的数据。

    前端页面:

    <body>
    <button class="btn btn-success btn-md">提交
    </button>
    <script>
        $('.btn').click(function () {
            $.ajax({
                url:'',
                data:JSON.stringify({'username':'jason','age':25}),  //将字段序列化成json格式的字符串
                type:'post',
                contentType:'application/json',  // 修改编码格式为json格式
                dataType:'json',
                success:function () {
                }
            })
        })
    </script>
    </body>
    

    后端:

    django在针对json格式编码的数据,不会做任何的处理,不会将其封装到request.POST或者request.FILES中,而在存在于request.body中,需要我们自己获取并进行处理(反序列化)。

    # 序列化方式一
    import json
    json_bytes = request.body
    json_str = json_bytes.decode('utf-8')
    json_str = json.loads(json_bytes)
    
    # loads补充:
    """
    json.loads括号内如果传入的是一个二进制格式的数据,
    那么内部会自动先解码再反序列化"""
    
    # 方式二 简写
    json_str = json.loads(json_bytes)  # 括号内直接放二进制的数据。
    

    ajax发送文件

    前端

    ajax在发送文件时需要借助与js内置对象FormDate获取一个formDate对象,然后往对象内append属性,添加属性的时既可以添加普通的键值对也可以添加文件对象,ajax数据部分直接放formDate对象即可。

    发送文件必须指定的两个参数:

    • contentType:false:告诉django不要使用任何的编码方式编码,django后端会自动识别formDate对象
    • process:false:告诉浏览器不要对数据进行任何的处理。
    <body>
    <input type="text" class=" form-control" id="d1">
    <input type="file" class=" form-control" id="d2">
    <button class="btn btn-success" id="d3">点我</button>
    <script>
        $('#d3').on('click',function () {
            		// 1 需要先利用FormData内置对象获取一个FormDate对象,
                    let formDate_obj = new FormData();
            		// 2 添加普通的键值对
                    formDate_obj.append('username',$('#d1').val());
            		// 3 添加文件对象
                    formDate_obj.append('myfile',$('#d2')[0].files[0]);
            		// $('#d2')查询到是jQuery对象,取索引[0]转为标签对象,
            		// 标签对象才有获取文件对象的方法files,点files获取文件对象,  				   // 取索引[0]获取到真正的文件。
            	// 4 将对象基于ajax发送给后端
                $.ajax({
                    url:'',
                    type:'post',
                    data:formDate_obj,
                    contentType:false,
                    processData:false,
                    success:function (args) {
                    }
                })
        })
    </script>
    </body>
    

    后端

    在request.POST获取文件数据并进行处理。

    def ab_file(request):
        if request.is_ajax():
            if request.method == 'POST':
                print(request.POST)
                print(request.FILES)
        return render(request,'ab_file.html')
    

    django后端能够直接识别到formdata对象并且能够将内部的普通键值自动解析并封装到request.POST中,文件数据自动解析并封装到request.FILES中

    django自带的序列化组件(为drf做铺垫)

    前后端分离:

    在写前后端分离的项目时,前端页面无法使用模版语法获取数据,需要在后端将数据序列化好之后再传给前端,前端才能识别。
    一般作为后端开发的程序员只需要写代码将数据处理好,能够序列化返回给前端,之后再写一个接口文档 告诉前端每个字段代表的意思即可。

    需求:在前端获取到后端用户表里面所有的数据,并且要是列表套字典的形式。

    纯手动序列化数据:

    def seria_json(request):
        import json
        user_queryset = models.User.objects.all()
        list_1 = []
        for user_obj in user_queryset:
            tem_dict ={
                'name':user_obj.name,
                'age':user_obj.age,
                'gender':user_obj.get_gender_display()
            }
            list_1.append(tem_dict)
        list_1 = json.dumps(list_1)
        return HttpResponse(list_1)
    

    这样的方式过于繁琐,并且字段过多时一个个添加键值对不现实。

    借助与django序列化组件serializers

    from django.core import serializers
    res = serializers.serialize('json',user_queryset)  
     """
    第一个参数是序列化的格式,第二个参数直接放包含表中所有数据的queryset对象即可,
    会自动帮你将数据变成json格式的字符串,并且内部非常的全面"""
     return HttpResponse(res)
    
    

    还可以用一些网址对json格式的数据进行解析格式化数据。

    解析格式化数据

    格式化之后的数据

    """
    [{
    	"model": "app01.user",
    	"pk": 1,
    	"fields": {
    		"name": "jaosn",
    		"age": 18,
    		"gender": 1
    	}
    }, {
    	"model": "app01.user",
    	"pk": 2,
    	"fields": {
    		"name": "tank",
    		"age": 19,
    		"gender": 2
    	}
    
    }]"""
    

    写接口就是利用序列化组件渲染数据然后写一个接口文档,该交代交代一下就可以了。

    AJAX结合sweetalert

    AJAX结合sweetalert实现删除的二次确认

    <script>
        $('.del').on('click',function () {
            let deleteElement =$(this)
            swal({
              title: "你确定要删吗",
              text: "删了数据就没有了哦!",
              type: "warning",
              showCancelButton: true,
              confirmButtonClass: "btn-danger",
              confirmButtonText: "是的!",
              cancelButtonText: "算了!",
              closeOnConfirm: false,
              closeOnCancel: false,
              showLoaderOnConfirm: true
            },
            function(isConfirm) {
              if (isConfirm) {
                  $.ajax({
                      // 1. 删除数据的主键值拼接在url后面
                      // url:'/user_delete/'+deleteElement.attr('delete_id'),
                      url:'/user_delete/',
                      // 2. 删除数据的主键值放在请求体里面
                      data:{'delete_id':deleteElement.attr('delete_id')},
                      type:'post',
                      success:function(args){
    					// 判断响应状态码 然后做不同的处理
                          if(args.code===1000){
                              swal('删了', args.msg, "success")
                              // 1.直接刷新当前页面
                              {#window.location.reload()#}
                               // 2.利用DOM操作 动态刷新
                              deleteElement.parent().parent().remove()
                          }
                          else{
                              swal('完了', '出现了未知的错误', "info")
                          }
                      }
                  })
              } else {
                swal("算了算了", "工作要紧", "error");
              }
            });
            })
    </script>
    

    后端:

    def user_delete(request):
        from django.http import JsonResponse
        import time
        if request.is_ajax():
            time.sleep(3)
            delete_id = request.POST.get('delete_id')
            back_dict = {'code': 1000, 'msg': ''}  # code响应状态码用于前端判断是否删除成功
            models.User.objects.filter(pk=delete_id).delete()
            back_dict['msg'] = '数据已经删除'
            return JsonResponse(back_dict)
    

    批量插入

    当插入的数据量很大时一条条插入数据耗时较长,选择批量插入操作时间会大大降低,提升效率。。

    def batch_create(request):
        # 第一种:一条条插入
        # for i in range(1000):
        #     models.Book.objects.create(title=f'第{i}书')
        # book_queryset = models.Book.objects.all()
    
        # 第二种:使用bulk_create批量插入
        obj_list = []
        for i in range(10000):
            book_obj = models.Book(title=f'第{i}本书')
            obj_list.append(book_obj)
        models.Book.objects.bulk_create(obj_list)
        book_queryset = models.Book.objects.all()
        return render(request, 'batch_create.html', locals())
    
  • 相关阅读:
    AUTOCAD二次开发-----删除一个图层里面的所有对象
    AutoCAD .NET: 遍历模型空间
    c# 将dwg文件转化为pdf
    C# 读取CAD文件缩略图(DWG文件)
    C#.Net实现AutoCAD块属性提取
    用.NET从外部dwg文件导入块
    AutoCAD二次开发(.Net)之获取LSP变量的值
    AutoCAD二次开发(.Net)之创建图层Layer
    Ceilometer和Gnocchi的监控架构解析
    《Python核心编程》笔记
  • 原文地址:https://www.cnblogs.com/zhangtieshan/p/13054273.html
Copyright © 2011-2022 走看看