魔力python---django---ajax

0 json简要知识

  1. json(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式.

json是基于ECMAScript(w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据.
简洁和清晰的层次结构使JSON成为理想的数据交换语言.易于人阅读和编写,同时也方便机器解析和生成,有效提升网络传输效率.

  1. json是从js拿出的一个对象,也可以说json是js的一个子集.

json的格式来源于js的格式
json的格式来源于js的格式

json补充
json补充

json数据类型与python对比
json数据类型与python对比

要知道:json格式来源于js的格式

3.json支持单引号,也支持双引号,也支持没有引号

 //在js中,{}这样的类型叫做对象,js中没有字典一说
 data = {
    'name':'haiyan',
    "name":"haiyan",
     name:"haiyan"        
}    
    //js对象默认会把自己的键当成字符串处理,所以可以加引号也可以不加

4.json格式:

  1. json只认双引号
  2. json一定是一个字符串
    前端ajax拿到后端返回的一个python的json模块序列化之后的一个json字符串,那么js通过自己的json接口,将接受到的json字符串来反序列化为js自己语言能够识别的数据类型,然后再进行操作。          
    相当于我有一个json方法,你有一个json方法,你给我发数据必须是json字符串的格式,那么你就需要将你的数据类型序列化为json的字符串,那么序列化的时候,就把你的数据序列化为了符合json标准的字符串,然后我接收到这个字符串之后,我通过我的json方法,将数据转换为我的语言支持的数据类型。在进行反序列化的时候,如果你的字符串不符合json的格式,那么反序列化的时候就会报错,所以只要你是通过json序列化成的字符串,都是能够json反序列化的,因为json序列化的时候,就把你的数据改为了符合json标准的字符串形式,例如:里面的单引号,序列化后变成了双引号。

5.合格的json对象

["one", "two", "three"]

{ "one": 1, "two": 2, "three": 3 }

{"names": ["张三", "李四"] }

[ { "name": "张三"}, {"name": "李四"} ]

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

7.python的序列化(dumps)和反序列化(loads)

import json
i = 10
s = "dsfdsf"
l = [11,22,33]
dic = {"name":"haiyna","age":22}
b = True
#把基本数据类型转换成字符串的形式
print(json.dumps(i),type(json.dumps(i)))   #10 <class 'str'>
print(json.dumps(s),type(json.dumps(s)))   #"dsfdsf" <class 'str'>
print(json.dumps(l),type(json.dumps(l)))   #[11, 22, 33] <class 'str'>
print(json.dumps(dic),type(json.dumps(dic)))  #{"name": "haiyna", "age": 22} <class 'str'>
print(json.dumps(b),type(json.dumps(b)))  #true <class 'str'>
# ===============json反序列化=============
d = {"a":1,"b":"fdgfd"}
data = json.dumps(d)
print(data,type(data))
f = open("a.txt","w")
f.write(data)   #注意这会写进去的字符串时双引号的格式
f.close()
# ===============json序列化=============
f = open("a.txt","r")
datat = f.read()
print(datat,type(datat))   #{"a": 1, "b": "fdgfd"} <class 'str'>
data = json.loads(datat)
print(data,type(data))  #{'a': 1, 'b': 'fdgfd'} <class 'dict'>
  1. js的序列化(stringify)与反序列化(parse)

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

parse英[pɑːz]美[pɑːrs]
v.(对句子) 作语法分析; 作句法分析;

<script>
//===========js中的json序列化===========
s = '{"name":1}';    
var data = JSON.parse(s);
console.log(data);
console.log(typeof data);   //object
//===========js中的json的反序列化=======
s2={'name':'yuan'};
console.log(JSON.stringify(s2),typeof JSON.stringify(s2))  //string
</script>

对比可见两者的异同(简直完全相同!)
9.JSON和XML
参考链接1

  1. js的stringify与parse方法
    JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象 
    JSON.parse('{"name":"chao"}');

JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。 
JSON.stringify({"name":"chao"})

11.JsonResponse的用处(数据交互的序列化问题)
 当我们给ajax回复的不是一个字符串,而是其他数据类型的时候,需要我们将数据转换为json字符串进行发送,这样好配合js进行json字符串的处理,不然发送或者接受的是普通字符串的话,没办法处理成原来的数据类型。  这就用到了前面的视图函数中JsonResponse了

12.Django内置的serializers做序列化

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)

13.补充
SweetAlert插件应用(模态对话框确认删除)
下面链接第六章
ajax的SweetAlert插件

14.同源策略和Jsonp
上面链接第七章(涉及不同浏览器使用
15.CORS)
上面链接第七章(涉及不同浏览器使用

1 什么是ajax?

ajax:(Asynchronous JavaScript And XML),异步的JavaScript和XML.
也就是使用Javascript语言和服务器进行异步交互,传输的数据是XML和json(现基本使用json数据).
ajax不是新的编程语言,而是一种使用现有标准的新方法.
ajax的特点:
局部刷新(整个过程没有刷新,只是刷新页面中的局部位置);
异步(当请求发出时,浏览器还可以进行其他操作,不需等待服务器响应).

ajax优点:效率高.
常用场景:

  1. 验证;
  2. 表单填写.

ajax会用到更多的JavaScript代码,这些代码倾向于在浏览器运行更长时间,尽量在核实的地方用.

补充:
前端向后端发送数据的方式:
GET:地址栏,a标签,Form表单
POST:Form表单
now,it's ajax show time! ajax也是前端向后端发送数据的一种方式.

ajax原理

1.1使用JavaScript获得浏览器内置的AJAX引擎(XMLHttpRequest对象)

1.2 通过AJAX引擎确定请求路径和请求参数

1.3 通知AJAX引擎发送请求, AJAX引擎会在不刷新浏览器地址栏的情况下,发送请求

2.1 服务器获得请求参数

2.2 服务器处理请求参数(添加、查询等操作)

2.3 服务器响应数据给浏览器

AJAX引擎获得服务器响应的数据,通过执行JavaScript的回调函数将数据传递给浏览器页面。

ajax传参

ajax在python中的实例(重要)

更多
ajax底层输出数据原理与示例
3.1 通过设置给AJAX引擎的回调函数获得服务器响应的数据

3.2 使用JavaScript在指定的位置,显示响应数据,从而局部修改页面的数据,达到局部刷新目的。

2 ajax属性和方法

1.url:
要求为String类型的参数,(默认为当前页地址)发送请求的地址。

2.type:
要求为String类型的参数,请求方式(post或get)默认为get。
注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3.timeout:
要求为Number类型的参数,设置请求超时时间(毫秒)。
此设置将覆盖$.ajaxSetup()方法的全局设置。

4.async:
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。
注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

5.cache:
要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。

6.data:
要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

7.dataType:
要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:
xml:返回XML文档,可用JQuery处理。
html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。
script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。
json:返回JSON数据。
jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。
text:返回纯文本字符串。

8.beforeSend
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。

            function(XMLHttpRequest){
               this;   //调用本次ajax请求时传递的options参数
            }

9.complete
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。

          function(XMLHttpRequest, textStatus){
             this;    //调用本次ajax请求时传递的options参数
          }

10.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。
(2)描述状态的字符串。

         function(data, textStatus){
            //data可能是xmlDoc、jsonObj、html、text等等
            this;  //调用本次ajax请求时传递的options参数
         }

11.error:
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:

       function(XMLHttpRequest, textStatus, errorThrown){
          //通常情况下textStatus和errorThrown只有其中一个包含信息
          this;   //调用本次ajax请求时传递的options参数
       }

12.contentType
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

13.dataFilter
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。

            function(data, type){
                //返回处理后的数据
                return data;
            }

14.dataFilter
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。

            function(data, type){
                //返回处理后的数据
                return data;
            }

15.global
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

16.ifModified
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

17.jsonp
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GET或POST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

18.username
要求为String类型的参数,用于响应HTTP访问认证请求的用户名。

19.password
要求为String类型的参数,用于响应HTTP访问认证请求的密码。

20.processData
要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。

21.scriptCharset
要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

**22.顺便说一下\(.each()函数**: \).each()函数不同于JQuery对象的each()方法,它是一个全局函数,不操作JQuery对象,而是以一个数组或者对象作为第1个参数,以一个回调函数作为第2个参数。回调函数拥有两个参数:第1个为对象的成员或数组的索引,第2个为对应变量或内容。

3 实例

HTML文件

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<h1>测试页面</h1>
<form action="" class="test1" method="post">
    {% csrf_token %}
    <label for="username">账号</label><input type="text" id="username" name="username">
    <label for="password">密码</label><input type="text" id="password" name="password">
    <input type="button" name="btn1" id="btn1" value="提交">
</form>
<script src="{% static 'jquery-3.4.1.js' %}"></script>
<script>
$('#btn1').on('click',function () {
    var username = $('#username').val();
    var password = $('#password').val();
    var csrftoken = $("[name='csrfmiddlewaretoken']").val();
    {#csrfmiddleware这句话也可以拿到data里面去,只要写了就能跨站请求csrf_token#}

    $.ajax({
        url:'{% url "test" %}',
        type:'post',
        data:{
            username:username,
            password:password,
            csrfmiddlewaretoken:csrftoken,
            contentType:false,
            dataType:'json',
        },
        {#上面的数据是请求,把数据从前端发送给后端;#}
        {#下面的数据是响应之后的,response(形参)是自动得到后端响应的数据,随便取名字都可以#}
        success: function (response) {
                console.log(response.status);
                if (response.status === '1') {
                    alert('呜呜呜,终于学会了')
                }
                else {
                    alert('你就是个酸菜鱼,又酸又菜又多余')
                }
            }
    });
    {#alert('666');#}
})
</script>
</body>
</html>

视图函数(views.py)

import json

from django.shortcuts import render,HttpResponse
from django.http import JsonResponse
from django import views

# Create your views here.

class Test(views.View):
    def get(self,request):
        return render(request,'test.html')

    def post(self,request):
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(r'username',r'password')
        ret = {'status':None,'msg':None}

        if username == '1' and password == '2':
            ret['status'] = '1'
            ret['msg'] = '呜呜呜,终于成功了'
        else:
            ret['status'] = '2'
            ret['msg'] = '你是一条酸菜鱼,又酸又菜又多余'

        print(ret)
        return JsonResponse(ret)

参考链接2---博客园:Tyler Ning
参考链接3
参考链接4

4 其他

4.1 ajax请求设置csrf_token

请求链接

4.2 文件上传

4.2.1 ajax文件上传

  1. data的格式是json格式转化
  2. 可能需要逐步添加数据append,不能直接在data里面写?(参考上面链接)
data:JSON.stringify({ //如果我们发送的是json数据格式的数据,那么csrf_token就不能直接写在data里面了,没有效果,必须通过csrf的方式3的形式来写,写在hearders(请求头,可以写一些自定制的请求头)里面,注意,其实contentType也是headers里面的一部分,写在里面外面都可以

form表单的文件上传

直接用<input type= "image">提交

views.py后端接收

def upload(request):
    if request.method == 'GET':
        return render(request,'upload.html')
    else:
        print(request.POST)
        username = request.POST.get('user')
        file_obj = request.FILES.get('file_obj') #获得文件数据对象
        print('>>>',file_obj,type(file_obj))
        #>>> jaden博客.txt <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>,一个文件对象,可以理解为一个文件句柄
        file_name = file_obj.name #jaden博客.txt
        print(file_name)
        # 将数据写到文件里面,需要名字,需要数据
        with open(file_name,'wb') as f: #直接把文件名字放这里,那么文件将直接生成在django的整个项目目录下,因为django配置的系统搜索的根路径就是咱们的项目文件夹路径,那个BASE_DIR,一般我们需要自己建立一个文件夹专门存放上传的文件      #所以需要我们自己来拼接一个路径放到这里,os.path.join(settings.BASE_DIR,'media','img',file_name)
            # f.write()  #不能一下写进去,占用的内容太多,要一点一点写
            for data in file_obj: #读数据
                f.write(data)  
                #每次读取的data不是固定长度的,和读取其他文件一样,每次读一行,识别符为\r  \n  \r\n,遇到这几个符号就算是读了一行       #for chunks in file_obj.chunks(): #chunks()默认一次返回大小为经测试为65536B,也就是64KB,最大为2.5M,是一个生成器         
                #  f.write(chunks)
posted on 2019-06-24 09:16  流云封心  阅读(63)  评论(0)    收藏  举报