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())
原文地址:https://www.cnblogs.com/zhangtieshan/p/13054273.html