Ajax前后端发送数据、文件、分页器和案例

Lucky-Hua / 2023-08-08 / 原文

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

前后端数据传输的请求方式有两种:get、post。主要研究post请求方式的编码格式
"""
get请求数据就是直接放在url?后面的:
  url?username=jason&password=123
"""

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

  urlencoded、form-data、json

可以朝后端发送post请求的方式:form表单、Ajax、postman

# 研究form表单发送post请求的时候数据的编码格式(请求头中的Content-Type:参数)

 1. 默认提交编码格式是:application/x-www-form-urlencoded,它的数据格式是:username=jason&password=123

问:针对application/x-www-form-urlencoded格式的数据,在Django后端是如何接收数据的

  Django后端针对符合urlcoded编码格式的数据都会自动帮你解析封装到request.POST中。

2. multipart/form-data编码格式,数据格式:boundary=----WebKitFormBoundary7iwnnLo3TDiHIAQz--->文件数据(二进制类型)

将编码格式从urlcoded改成form-data:form表单除了可以提交普通数据,还能够提交文件数据。

问:针对multipart/form-data格式的数据,Django后端是如何接收数据的

  针对普通数据django把数据封装到了request.POST中

  文件数据django把数据封装到了reuqest.FILES中

Ajax提交post请求的数据时,编码格式:application/x-www-form-urlencoded; 数据类型:a=1&b=2

django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中

Ajax提交json格式数据

前端向后端提交数据的时候一定要保证编码格式和数据的真正格式是一致的

提交json格式的数据必须满足两个条件:

  1. 你的编码格式必须是json格式的

  2. 你的数据必须是jsonl类型:{"a":1}
对于json格式的数据,django后端不在做任何的封装,数据是纯原生的,发送过来的数据是二进制形式的,需要我们自己进行处理二进制数据

例子:

html文件中:

<body>
<button class="btn btn-success" id="d1">提交</button>
<script>
    $('#d1').click(function () {
        $.ajax({
            url:'',
            type:'post',
            // 将{'username':'rui','age':18}对象序列化为json格式
            data:JSON.stringify({'username':'rui','age':18}),
            // 指定编码格式
            contentType:'json',
            //回调函数
            success:function (res) {
            }
        })

    })

</script>
</body>

views文件:

from django.shortcuts import render
import json
# Create your views here.
def index(request):
    if request.method =='POST':
        print(request.POST) # <QueryDict: {}>
        print(request.body) #数据格式是二进制 :b'{"username":"rui","age":18}'
        # 要解码并转成字符串
        json_bytes = request.body
        # json_str = json_bytes.decode('utf-8') #将二进制类型的数据解码为字符串类型
        # json_dict = json.loads(json_str) # 将字符串反序列化为json格式
        json_dict = json.loads(json_bytes) #  json.loads括号内如果传入了一个二进制格式的数据那么内部自动解码再反序列化
        print(json_dict) # {'username': 'rui', 'age': 18}
    return render(request,'index.html')

结果:

 Ajax提交json格式数据需要注意点:

  1.contentType参数指定成:application/json

  2.数据是真正的json格式数据

  3.django后端不会帮你处理json格式数据需要你自己去request.body获取并处理

Ajax提交文件数据(重要)

Ajax提交文件需要借助于js内置对象FormData

html文件中:前端

<body>
<p>
    username:<input type="text" id="d1" class="form-control">
</p>
<p>
    password:<input type="text" id="d2" class="form-control">
</p>
<p>
    上传文件:<input type="file" id="d3" class="form-control">
</p>
<button class="btn btn-danger" id="d4">提交</button>
<script>
    //绑定点击事件
    $('#d4').click(function () {
        // 1.需要先利用FormData内置对象
        var formDataObj = new FormData();
        // 2.在formDataObj对象中添加普通的键值对
        formDataObj.append('username',$('#d1').val()) //$('#d1').val()就是username具体的数据
        formDataObj.append('password',$('#d2').val())
        // 3.添加文件对象
        formDataObj.append('file',$('#d3')[0].files[0])// $('#d3')[0] 获取标签对象,$('#d3')[0].files[0]获取标签对象里的文件
        // 将对象基于Ajax发送给后端
        $.ajax({
            url:'',
            type:'post',
            data:formDataObj, //直接将对象放在data后面即可
            //ajax发送文件必须指定的两个参数
            contentType:false, //不需要使用任何编码,Django后端能够自动识别formdata对象
            processData: false, // 告诉浏览器不要对数据进行任何处理
            success:function (res) {

            }
        })
    })
</script>
</body>

如图:

 views文件:后端

# 接收文件数据
def ad_file(request):
    # 判断当前请求是否是ajax请求 返回布尔值
    if request.is_ajax():
        print(request.is_ajax()) # True
        if request.method == 'POST':
            print(request.POST)  #<QueryDict: {'username': ['rui'], 'password': ['123']}>
            print(request.FILES)  # <MultiValueDict: {'file': [<InMemoryUploadedFile: meizi.jpeg (image/jpeg)>]}>
    return render(request, 'ad_file.html')

如图:

 Ajax结合layer弹窗实现删除的二次确认

删除作者操作:

html页面:

{% extends 'home.html' %}


{% block content %}
    <h1 class="text-center">作者列表展示</h1>
    <a href="/authoradd/" class="btn btn-info">添加作者</a>
    <table class="table table-striped table-hover">
        <thead>
        <tr>
            <th>姓名</th>
            <th>年龄</th>
            <th>电话</th>
            <th>地址</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        {% for foo in author_queryset %}
            <tr class="tr_{{ foo.id }}">
                <td>{{ foo.name }}</td>
                <td>{{ foo.age }}</td>
                <td>{{ foo.author_detail.phone }}</td>
                <td>{{ foo.author_detail.addr }}</td>
                <td>
                    <a href="/authoradd/?id={{ foo.pk }}" class="btn btn-success">修改</a>
                    {#                    <a href="/authordelete/?id={{ foo.pk }}" class="btn btn-danger">删除</a>#}
                    <button class="btn btn-danger" delete_id="{{ foo.pk }}">删除</button>
                </td>
            </tr>
        {% endfor %}
        </tbody>
    </table>
{% endblock %}
{% block js %}
    <script>
        // 给删除按钮绑定点击事件
        $(".btn").click(function () {
            //删除的逻辑:当我们点击删除俺就的时候,应该获取点击行的id值,然后把这个id值传给后端,后端接收id值
            var d_id = $(this).attr('delete_id'); // $(this):是$(".btn")对象,delete_id:自定义属性,获取的是作者的id
            var _this = $(this); //$(this):还是$(".btn")对象,定义为新的变量方便后面的使用
            // 获取到id值之后,就发送Ajax请求,做一个二次确认
            layer.confirm('你确认要删除这条数据吗?', {
                btn: ['确定'] //按钮d
            }, function () {
                // 发送ajax请求 做个二次确认
                $.ajax({
                    url:'/authordelete/', // 这边不能不能为空(空就是当前地址),要指定删除的路由地址
                    type:'post',
                    data:{'id':d_id},//  'id':是传给后端的,d_id这个是具体的实际值,那么在后端获取时的id名应该和'id'一样
                    success:function (res) {
                        if(res.code == 200){
                            {#layer.msg(res.msg, {icon:1})#}
                            {#    location.reload(); //这种删除会立马刷新页面不会看到弹窗 #}
                            {#layer.msg(res.msg);#}
                            {#_this.parent().parent().remove(); //  一个parent就是往上找一个父辈#}
                            // 找到对应的tr行,然后删除这个tr行
                             layer.msg(res.msg); //接收后端返回的’删除成功‘
                            $(".tr_"+ d_id).remove(); // ".tr_"+id:字符串的拼接,结果="tr_{{ foo.id }}",d_id是最初获取的要被删除的id值
                        }
                    }
                });
            });
        })
    </script>
{% endblock %}

views页面:

# 删除作者,
def author_delete(request):
    id = request.POST.get('id') # 'id':从后端拿到id值
    models.Author.objects.filter(pk=id).delete()
    return JsonResponse({'code': 200, 'msg': '删除成功'})

 批量插入数据

以下是将数据一个一个插入数据库就会很慢,因为要访问数据库加入一条数据在访问数据库再加入数据,如果数量过多会导致数据库崩溃

  将需要添加的数据先放进一个列表里,然后再用数据库进行添加,节省事件,当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间

 结果: