Django 之AJAX

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 之AJAX相关的知识,希望对你有一定的参考价值。

day72 2018-06-27

 

1. 内容回顾

 

    1. 中间件
        1. 中间件概念
        2. 中间件应用的场景
            对请求和相应做全局修改/处理
            
        3. Django中间件的用法
            1. 按照格式要求自己写一个类
                1. from django.utils.deprecation import MiddlewareMixin
                    我们写的中间件的类要继承 MiddlewareMixin
                2. 定义相应的方法(5种可以选择)
                    1. process_request(self, request)
                        1. 何时执行
                        2. 执行的顺序  --> 注册的正序
                        3. 返回值
                            1. 返回None          --> 继续往后执行
                            2. 返回Response对象  --> 跳出直接返回响应(按照处理响应的操作继续往后执行)
                    
                    2. process_view(self, request, view_func, args, kwargs)
                        1. 何时执行
                        2. 执行的顺序     --> 注册的正序
                        3. 返回值
                            1. 返回None          --> 继续往后执行
                            2. 返回Response对象  --> 跳出直接返回响应(按照处理响应的操作继续往后执行)
                    
                    3. process_exception(self, request, exception)
                    
                    4. process_template_response(self, request, response)
                    
                    5. process_response(self, request, response)
                        1. 何时执行
                        2. 执行的顺序    --> 注册的倒序
                        3. 返回值
1. 必须返回一个response
View Code

 

  2. 去settings.py里注册/配置 我写的类

 https://pymotw.com/3/py-modindex.html

    importlib模块的基本使用

     

           

    2. Django请求的生命周期

    边画边说

    

 

 

  补充

    利用Django中间件实现网站访问频率限制。

    具体要求是:每个ip一分钟最多访问5次,超过5次就加入黑名单。

    提示:获取访问者ip的方法:request.META.get("REMOTE_ADDR")

 

    history = {

    ip: {"last": 09:20:10, "times": 1},

    }

    

 

 

 

2. 今日内容

https://www.cnblogs.com/liwenzhou/p/8718861.html

1. AJAX预备知识点

  1. Python

    dict    <==>    JSON格式字符串

 

    json.loads()

    json.dumps()

    python中序列化

              

 

 

 

2. JavaScript中:

  SON 指的是 javascript 对象表示法(JavaScript Object Notation)

  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;}  // 不能使用函数和日期对象
}

 

  obj      <==>  JSON格式字符串

  javaScript中序列化

  stringifyparse方法

  JavaScript中关于JSON对象和字符串转换的两个方法:

  JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象

  JSON.parse(\'{"name":"Q1mi"}\');
  JSON.parse(\'{name:"Q1mi"}\') ;   // 错误

  JSON.parse(\'[18,undefined]\') ;   // 错误

  JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。

  JSON.stringify({"name":"Q1mi"})

 

  JSON.parse()

  JSON.stringify()

XML的比较

SON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML 格式。

JSON 格式有两个显著的优点:书写简单,一目了然;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。所以,JSON迅速被接受,已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。

XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。

用XML表示中国部分省市数据如下:

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<country>
    <name>中国</name>
    <province>
        <name>黑龙江</name>
        <cities>
            <city>哈尔滨</city>
            <city>大庆</city>
        </cities>
    </province>
    <province>
        <name>广东</name>
        <cities>
            <city>广州</city>
            <city>深圳</city>
            <city>珠海</city>
        </cities>
    </province>
    <province>
        <name>台湾</name>
        <cities>
            <city>台北</city>
            <city>高雄</city>
        </cities>
    </province>
    <province>
        <name>新疆</name>
        <cities>
            <city>乌鲁木齐</city>
        </cities>
    </province>
</country>

 

用JSON表示如下:

 

 

 

{
    "name": "中国",
    "province": [{
        "name": "黑龙江",
        "cities": {
            "city": ["哈尔滨", "大庆"]
        }
    }, {
        "name": "广东",
        "cities": {
            "city": ["广州", "深圳", "珠海"]
        }
    }, {
        "name": "台湾",
        "cities": {
            "city": ["台北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["乌鲁木齐"]
        }
    }]
}

 
View Code

 

  由上面的两端代码可以看出,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON   所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得带宽。 

  示例

    页面输入两个整数,通过AJAX传输到后端计算出结果并返回。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>AJAX局部刷新实例</title>
</head>
<body>

<input type="text" id="i1">+
<input type="text" id="i2">=
<input type="text" id="i3">
<input type="button" value="AJAX提交" id="b1">

<script src="/static/jquery-3.2.1.min.js"></script>
<script>
  $("#b1").on("click", function () {
    $.ajax({
      url:"/ajax_add/",
      type:"GET",
      data:{"i1":$("#i1").val(),"i2":$("#i2").val()},
      success:function (data) {
        $("#i3").val(data);
      }
    })
  })
</script>
</body>
</html>

 

 
HTML
def ajax_demo1(request):
    return render(request, "ajax_demo1.html")

def ajax_add(request):
    i1 = int(request.GET.get("i1"))
    i2 = int(request.GET.get("i2"))
    ret = i1 + i2
    return JsonResponse(ret, safe=False)
views
urlpatterns = [
    ...
    url(r\'^ajax_add/\', views.ajax_add),
    url(r\'^ajax_demo1/\', views.ajax_demo1),
    ...   
]
url

 

2. AJAX

  1. AJAX是什么?

    1、简单介绍

      我们以前知道的前端向后端发送数据的方式有:

      GET:地址栏、a标签、Form表单

      POST:Form表单

      那么现在我们在学习一种:那就是ajax

      ajax:也是前端向后端发送数据的一种方式

    AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

    Ajax的特点:

      异步交互:当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

      局部刷新:    整个过程中页面没有刷新,只是刷新页面中的局部位置而已!

    js的局部刷新:

  AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

 

2AJAX常见应用情景

    搜索引擎根据用户输入的关键字,自动提示检索关键字。

    还有一个很重要的应用场景就是注册时候的用户名的查重。

    其实这里就使用了AJAX技术!当文件框发生了输入变化时,使用AJAX技术向服务器发送一个请求,然后服务器会把查询到的结果响应给浏览器,最后再把后端返回的结果展示出来。

  • 整个过程中页面没有刷新,只是刷新页面中的局部位置而已!
  • 当请求发出后,浏览器还可以进行其他操作,无需等待服务器的响应!

       

  当输入用户名后,把光标移动到其他表单项上时,浏览器会使用AJAX技术向服务器发出请求,服务器会查询名为lemontree7777777的用户是否存在,最终服务器返回true表示名为lemontree7777777的用户已经存在了,浏览器在得到结果后显示“用户名已被注册!”。

  • 整个过程中页面没有刷新,只是局部刷新了;
  • 在请求发出后,浏览器不用等待服务器响应结果就可以进行其他操作; 

       3AJAX的优缺点

    优点:

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

           ajax怎么用

                  

                 

 

               一个请求没有响应我们可以在发送其他请求实例:

            html

                 

 

    views

              

 

 

2. jQuery实现的AJAX

    jQuery实现的AJAX

      最基本的jQuery发送AJAX请求示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ajax test</title>
  <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<button id="ajaxTest">AJAX 测试</button>
<script>
  $("#ajaxTest").click(function () {
    $.ajax({
      url: "/ajax_test/",
      type: "POST",
      data: {username: "Q1mi", password: 123456},
      success: function (data) {
        alert(data)
      }
    })
  })
</script>
</body>
</html>
View Code

 views.py

def ajax_test(request):
    user_name = request.POST.get("username")
    password = request.POST.get("password")
    print(user_name, password)
    return HttpResponse("OK")

  $.ajax参数

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

              

 $("#b1").on("click", function () {
    $.ajax({
      url:"/ajax_add/",
      type:"GET",
      data:{"i1":$("#i1").val(),"i2":$("#i2").val(),"hehe": JSON.stringify([1, 2, 3])},
      success:function (data) {
        $("#i3").val(data);
      }
    })
  }) 

js版ajax

html

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>Title</title>

    <meta name="viewport" content="width=device-width, initial-scale=1">

</head>

<body>

<button id="b1">点我 发送 JS 版AJAX请求</button>

<script>

    let b1Ele = document.getElementById("b1");

    b1Ele.onclick = function () {

        // 1. 生成xmlHttp对象

        let xmlHttp = new XMLHttpRequest();

        // 2. 调用xmlHttp的open方法设置请求相关配置项

        xmlHttp.open("POST", "/ajax_js/", true);

        // 3. 设置请求头

        xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

        // 4. 调用send方法发送数据

        xmlHttp.send("username=张曌&age=16");

        // 5. 处理返回的响应

        xmlHttp.onreadystatechange = function () {

            if (xmlHttp.readyState === 4 && xmlHttp.status === 200) {

                alert(xmlHttp.responseText);

            }

        };

 

    }

 

</script>

</body>

</html>

Views

 
View Code

 

 

   1请求参数

 

        ######################------------data---------################
        data: 当前ajax请求要携带的数据,是一个json的object对象,ajax方法就会默认地把它编码成某种格式
             (urlencoded:?a=1&b=2)发送给服务端;此外,ajax默认以get方式发送请求。
        function testData() {
               $.ajax("/test",{     //此时的data是一个json形式的对象
                  data:{
                    a:1,
                    b:2
                  }
               });                   //?a=1&b=2
######################------------processData---------################
        processData:声明当前的data数据是否进行转码或预处理,默认为true,即预处理;if为false,
             那么对data:{a:1,b:2}会调用json对象的toString()方法,即{a:1,b:2}.toString()
             ,最后得到一个[object,Object]形式的结果。
            
######################------------contentType---------################
        contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
             用来指明当前请求的数据编码格式;urlencoded:?a=1&b=2;如果想以其他方式提交数据,
             比如contentType:"application/json",即向服务器发送一个json字符串:
               $.ajax("/ajax_get",{
             
                  data:JSON.stringify({
                       a:22,
                       b:33
                   }),
                   contentType:"application/json",
                   type:"POST",
             
               });                          //{a: 22, b: 33}
        注意:contentType:"application/json"一旦设定,data必须是json字符串,不能是json对象
        ######################------------traditional---------################
        traditional:一般是我们的data数据有数组时会用到 :data:{a:22,b:33,c:["x","y"]},
              traditional为false会对数据进行深层次迭代;  
        
View Code

 

响应参数

 

/*

dataType:  预期服务器返回的数据类型,服务器端返回的数据会根据这个值解析后,传递给回调函数。
            默认不需要显性指定这个属性,ajax会根据服务器返回的content Type来进行转换;
            比如我们的服务器响应的content Type为json格式,这时ajax方法就会对响应的内容
            进行一个json格式的转换,if转换成功,我们在success的回调函数里就会得到一个json格式
            的对象;转换失败就会触发error这个回调函数。如果我们明确地指定目标类型,就可以使用
            data Type。
            dataType的可用值:html|xml|json|text|script
            见下dataType实例

*/
View Code

 

实例:

 1 from django.shortcuts import render,HttpResponse
 2 from django.views.decorators.csrf import csrf_exempt
 3 # Create your views here.
 4 
 5 import json
 6 
 7 def login(request):
 8 
 9     return render(request,\'Ajax.html\')
10 
11 
12 def ajax_get(request):
13 
14     l=[\'alex\',\'little alex\']
15     dic={"name":"alex","pwd":123}
16 
17     #return HttpResponse(l)      #元素直接转成字符串alexlittle alex
18     #return HttpResponse(dic)    #字典的键直接转成字符串namepwd
19     return HttpResponse(json.dumps(l))
20     return HttpResponse(json.dumps(dic))# 传到前端的是json字符串,要想使用,需要JSON.parse(data)
21 
22 //---------------------------------------------------
23     function testData() {
24 
25         $.ajax(\'ajax_get\', {
26            success: function (data) {
27            console.log(data);
28            console.log(typeof(data));
29            //console.log(data.name);
30            //JSON.parse(data);
31            //console.log(data.name);
32                                      },
33            //dataType:"json",
34                             }
35                        )}
36 
37 注解:Response Headers的content Type为text/html,所以返回的是String;但如果我们想要一个json对象
38     设定dataType:"json"即可,相当于告诉ajax方法把服务器返回的数据转成json对象发送到前端.结果为object
39     当然,
40         return HttpResponse(json.dumps(a),content_type="application/json")
41 
42     这样就不需要设定dataType:"json"了。
43     content_type="application/json"和content_type="json"是一样的!

 
View Code

 

  2ajax的参数补充

- type不写的话默认是GET

- dataType和ContentType:

dataType: 浏览器发给服务器希望返回的数据类型 。。如果我们明确地指定目标类型,就可以使用data Type。

ContentType:

请求头里有:浏览器告诉服务器内容的类型

响应头里也有:服务器响应浏览器的内容

4、JS和JQuery对象之间的转换

jQuery对象加[0]就转换成了dom对象

dom对象加$符就转换成了jquery对象

5、processDate 默认为True ,预处理;     如果改为False,不做预处理

来自 <http://www.cnblogs.com/haiyan123/p/7829080.html>

 
View Code

 

3. AJAX优缺点

   1. 优点:

    局 部更新

    异步

  2. 缺点:

    服务端压力大

4. AJAX处理csrf_token

  AJAX请求如何设置csrf_token

  方式1

    通过获取隐藏的input标签中的csrfmiddlewaretoken值,放置在data中发送。

 

$.ajax({
  url: "/cookie_ajax/",
  type: "POST",
  data: {
    "username": "Q1mi",
    "password": 123456,
    "csrfmiddlewaretoken": $("[name = \'csrfmiddlewaretoken\']").val()  // 使用JQuery取出csrfmiddlewaretoken的值,拼接到data中
  },
  success: function (data) {
    console.log(data);
  }
})

 

方式2

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

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

一定放jquest后面

 

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

 

或者用自己写一个getCookie方法:

 

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\');

 

每一次都这么写太麻烦了,可以使用$.ajaxSetup()方法为ajax请求统一设置。

 

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);
    }
  }
});

在前面加上上面自己写的每一次调用导入就行 每一个跟jquest一起导入

 

来自 <https://www.cnblogs.com/liwenzhou/p/8718861.html>

5. AJAX上传文件

  Ajax上传文件(利用FormData):既可以处理二进制,又可以处理字典,列表啊等

  FormData是什么呢?

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个"表单".比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.

所有主流浏览器的较新版本都已经支持这个对象了,比如Chrome 7+、Firefox 4+、IE 10+、Opera 12+、Safari 5+。

注意:下文中的几个需要解释的

$("#upload") 拿到的是一个集合
$("#upload")[0]  就是一个dom对象
$("#upload")[0].files   拿到的是一个filelist
$("#upload")[0].files[0]  拿到的是当前最近的文件对象 以上是关于Django 之AJAX的主要内容,如果未能解决你的问题,请参考以下文章

Django之原生Ajax操作

django基础知识之Ajax:

django之jquery完成ajax

Django之AJAX请求

django之使用jquery完成ajax

Django之ajax的数据传输和分页器