zoukankan      html  css  js  c++  java
  • Django Ajax

    Ajax

    1    大坑
        如果在form表单中,写button和input是submit类型,会触发form表单的提交
        如果不想触发
            不写在form表单里面
            将input的type写成button
       
    2   大坑
        后端响应格式如果是:html/text格式,ajax接收到的数据后需要自己转成对象
        总结:后端返回数据,统一都用JsonResponse
        
    3   大坑
        如果使用了ajax,后端就不要返回rediret,render,HttpResponse
        直接返回JsonResponse

    详情参见:https://www.cnblogs.com/Dominic-Ji/p/9234099.html

    """
    异步提交:请求发出去 不会卡在这里,可以干其他事情
    局部刷新: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
    """

     

  • 相关阅读:
    Mybatis插件开发入门,运行原理,例子
    ActiveMQ是什么,为什么使用MQ
    sql优化
    用户注册流程
    JMS入门Demo
    运维自动化之Ansible
    ceph安装部署
    ceph工作原理
    linux进程
    任务计划
  • 原文地址:https://www.cnblogs.com/ZhZhang12138/p/14875553.html
Copyright © 2011-2022 走看看