• Django之AJAX


    老师的博客:https://www.cnblogs.com/liwenzhou/p/8718861.html

    AJAX的准备知识

    在我们以前的知识中

    2. 我们之前已经学过的发请求的方式:
            1. 直接在地址栏输入URL回车     GET请求
            2. a标签                       GET请求
            3. form表单                    GET/POST请求
            4. AJAX                        GET/POST请求

    json

    合格的json对象:

    ["one", "two", "three"]
    { "one": 1, "two": 2, "three": 3 }
    {"names": ["张三", "李四"] }
    [ { "name": "张三"}, {"name": "李四"} ] 

     不合格的json对象:

    { name: "张三", 'age': 32 }  // 属性名必须使用双引号
    [32, 64, 128, 0xFFF] // 不能使用十六进制值
    { "name": "张三", "age": undefined }  // 不能使用undefined
    { "name": "张三",
      "birthday": new Date('Fri, 26 Aug 2011 07:13:10 GMT'),
      "getName":  function() {return this.name;}  // 不能使用函数和日期对象
    }

    stringify与parse

    loads与dumps

    import json
    a = '{"name":"xpg", "age":18}'
    ret1=json.loads(a)
    print(ret1, type(ret1))
    ret2=json.dumps(ret1)
    print(ret2, type(ret2))

    结果

    {'age': 18, 'name': 'xpg'} <class 'dict'>
    {"age": 18, "name": "xpg"} <class 'str'>

     AJAX

    示例:

    在urls中

    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^ajax/',views.ajax),
        url(r'^ajax_add/',views.ajax_add)
    ]

     在app01中的views中:

    def ajax(request):
        return render(request, "AJAX测试.html")
    def ajax_add(request):
        print(request.GET)
        ret1=int(request.GET.get("i1"))
        ret2=int(request.GET.get("i2"))
        ret3 = ret1 + ret2
        return HttpResponse(ret3)

    在html文件中

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>AJAX示例</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <script src="/static/jQuery.js"></script>
        <link href="/static/normalize.css" rel="stylesheet">
        <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
        <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
        <link href="/static/toastr/toastr.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
    <p style="padding-top: 30px;">
        <input type="text" name="v1" id="d1">+
        <input type="text" name="v2" id="d2" >=
        <input type="text" id="d3">
        <button class="btn btn-danger" id="b1">提交</button>
    </p>
    </div>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <script src="/static/jQuery.js"></script>
    <script src="/static/toastr/toastr.min.js"></script>
    <script>$("#b1").on("click", function () {
        $.ajax({
          url:"/ajax_add/",{#提交数据的地方#}
          type:"GET",{#提交数据的方式#}
          data:{"i1":$("#d1").val(),"i2":$("#d2").val()},{#数据的内容#}
          success:function (data) {
            $("#d3").val(data);
            alert("局部啥刷新了一次")
    
          }{#执行成功之后,data表示url,return 过来的内容#}
        })
      })
    
    
    
    
    </script>
    </body>
    html文件

     注意

    data参数中的键值对,如果值值不为字符串,需要将其转换成字符串类型。

    data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},

    AJAX的常见场景

    注册时的实时监测

    AJAX的优点

    优点:

    • AJAX使用JavaScript技术向服务器发送异步请求;
    • AJAX请求无须刷新整个页面;
    • 因为服务器响应内容不再是整个页面,而是页面中的部分内容,所以AJAX性能高; 

    AJAX请求如何设置csrf_token

    上面的示例使用get请求实现的,当然还可以用post请求来实现这样的功能

    当然你可以把setting中csrf给注释了,下面是不注释的方法

    方法一:

    在HTML中

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <title>AJAX示例</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <script src="/static/jQuery.js"></script>
        <link href="/static/normalize.css" rel="stylesheet">
        <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
        <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
        <link href="/static/toastr/toastr.min.css" rel="stylesheet">
    </head>
    <body>
    <div class="container">
        {% csrf_token %}
    <p style="padding-top: 30px;">
        <input type="text" name="v1" id="d1">+
        <input type="text" name="v2" id="d2" >=
        <input type="text" id="d3">
        <button class="btn btn-danger" id="b1">提交</button>
    </p>
    </div>
    <script src="/static/bootstrap/js/bootstrap.min.js"></script>
    <script src="/static/jQuery.js"></script>
    <script src="/static/toastr/toastr.min.js"></script>
    <script>$("#b1").on("click", function () {
        $.ajax({
          url:"/ajax_add/",{#提交数据的地方#}
          type:"POST",{#提交数据的方式#}
          data:{"i1":$("#d1").val(),
              "i2":$("#d2").val(),
              "csrfmiddlewaretoken":$("[name='csrfmiddlewaretoken']").val()
          },{#数据的内容#}
          success:function (data) {
            $("#d3").val(data);
            alert("局部啥刷新了一次")
    
          }{#执行成功之后,data表示url,return 过来的内容#}
        })
      })
    
    
    
    
    </script>
    </body>
    </html>
    HTML 

     注意:

      此时的的key是csrfmiddlewaretoken

     在form表单中,提交时会默认把所有的键值对都给提交了。但是在ajax中,由于不是form所以csrf_taken需要自己提交

    在views中:

    def ajax_add(request):
        print(11111)
        if request.method == "POST":
            print(request.POST)
            ret1 = int(request.POST.get("i1"))
            ret2 = int(request.POST.get("i2"))
            ret3 = ret1 + ret2
            return HttpResponse(ret3)
        print(request.GET)
        ret1=int(request.GET.get("i1"))
        ret2=int(request.GET.get("i2"))
        ret3 = ret1 + ret2
        return HttpResponse(ret3)

     方法二

    通过获取返回的cookie中的字符串 放置在请求头中发送。

    注意:需要引入一个jquery.cookie.js插件。

    $.ajax({
      url: "/cookie_ajax/",
      type: "POST",
      headers: {"X-CSRFToken": $.cookie('csrftoken')},  // 从Cookie取csrftoken,并设置到请求头中
      data: {"username": "Q1mi", "password": 123456},
      success: function (data) {
        console.log(data);
      }
    })

    方法三

    function getCookie(name) {
        var cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
    var csrftoken = getCookie('csrftoken');
    function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
      return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
    }
    
    $.ajaxSetup({
      beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
          xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
      }
    });

    将上面的代码方在一个js的文件夹里面,然后倒入就好,在写函数时就不需要传csrf的参数了。

    注意:

    • 如果使用从cookie中取csrftoken的方式,需要确保cookie存在csrftoken值。
    • 如果你的视图渲染的HTML文件中没有包含 {% csrf_token %},Django可能不会设置CSRFtoken的cookie。
    • 这个时候需要使用ensure_csrf_cookie()装饰器强制设置Cookie。
    复制代码
    django.views.decorators.csrf import ensure_csrf_cookie
    
    
    @ensure_csrf_cookie
    def login(request):
        pass
    复制代码

    更多细节详见:Djagno官方文档中关于CSRF的内容

    AJAX上传文件

     见老师的博客

    序列化

    当然Django一般会处理,转化为字符串的,但是如果时字典的话,还是需要json。

    如果用json的话,json对于时间格式转化为bytes会报错

    TypeError: datetime.date(2019, 5, 14) is not JSON serializable

    一般不用。

    json的内部有个序列化的模块

    def books_json(request):
        book_list = models.Book.objects.all()[0:10]
        from django.core import serializers
        ret = serializers.serialize("json", book_list)
        return HttpResponse(ret)

    补充一个SweetAlert插件示例

     

    点击下载Bootstrap-sweetalert项目

    下载好文件,解压,然后需要两个核心文件:

    新建文件夹,sweetalert,然后将两个文件放在里面。

    导入到Django的静态文件里面。

    然后HTML的模板改为如下

    下面是使用方法

    官网示例

    简单版

    <script>
        $(".btn-danger").on("click", function () {
            swal("你好","文本内容","error")})
    </script>

    第一个参数表示文本的题目

    第二个参数是表示文本的内容

    第三个参数是表图标 有 "warning""error""success" and "info".可选,其他不能生效。

    进阶版

    <script>
        $(".btn-danger").on("click", function () {
            swal({
                title: "你确定要删除吗?", {#题目#}
                text: "删除可就找不回来了哦!", {#文本#}
                icon: "info", {#图标#}
                showCancelButton: true, {#是否去取消按钮#}
                confirmButtonClass: "btn-danger", {#确认按钮的颜色#}
                confirmButtonText: "删除", {#确认按钮的文本#}
                cancelButtonText: "我后悔了", {#  取消按钮的文本#}
                closeOnConfirm: false,{#点击确认建后关闭#}
                function() { {#点击确认后的操作#}
                    var deleteId = $(this).parent().parent().attr("data_id");{#找到标签#}
                    $.ajax({{#执行函数#}
                        url: "/delete_book/",
                        type: "post",
                        data: {"id": deleteId},
                        success: function (data) {
                            if (data.status === 1) {
                                swal("删除成功!", "你可以准备跑路了!", "success");
                            } else {
                                swal("删除失败", "你可以再尝试一下!", "error")
                            }
                        }
                })
    
    </script>

     补充

    关于数据的转化

    在html

    但html文件传送的是列表时,需要注意的点的加上几个参数。

    traditional: true,
    data:{"k":"v1", "k2":[1,2,23]},

    或者

     data:{"k":"v1", "k2":JSON.stringify([1,2,23])},

    然后在views中得到数据

    ret=request.POST.getlist("k2")

    在views中

     li={"k1":"v1", "k2": [2,2,3,[3.4]]}
            li=json.dumps(li)
            return HttpResponse(li)

    在html中

    datatype:"json",
    
                success:function(args){
                    args=JSON.parse(args);
                swal(args);
                $("#s1").val(args);
                console.log(args,typeof(args))
                }

    这样得到的args才是object

  • 相关阅读:
    elasticsearch7.1 安装启动报错
    jvm调优
    基于redis实现IP访问频次控制
    docker 搭建redis集群
    Tomcat安全配置与性能优化
    mybaties 的 applicationContext.xml
    SSH阶段常见错误及说明
    hibernate 7种映射关系
    (四)SpringBoot如何定义消息转换器
    java之package与import
  • 原文地址:https://www.cnblogs.com/accolade/p/10849590.html
Copyright © 2020-2023  润新知