Django与Ajax

it2023-09-20  74

文章目录

一 Django与Ajax(一) Ajax介绍1 什么是Ajax2 同步与异步交互 (二) 基于jQuery的Ajax实现(三) 案例**1 通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面**2 基于Ajax进行登录验证 (四) Ajax文件上传1 请求头ContentType的三种编码2 基于Form表单上传文件3 基于Ajax上传文件**(1) 基于Ajax上传文件的模板** 4 总结 (五) Ajax提交json格式数据(六) 了解Django内置序列化器serializers

一 Django与Ajax

(一) Ajax介绍

1 什么是Ajax

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

# 异步 Javascript 和 XML -异步:跟同步是对应的 -javascript:通过javascript来操作,发送请求 ,到服务端 -xml:数据交互使用xml,现在主流使用json格式 # xml 与 json -xml:可阅读性比较高,解析复杂,占的空间大 <name>lqz</name> <age>19</age> -json:可阅读性比较高,解析简单,占的空间小 {"name":"lqz","age":19} # 优点: -浏览器页面**局部刷新**(js的dom(Document Object Model)操作) -通过js发送http的请求(go,java,php,requset)

2 同步与异步交互

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

(二) 基于jQuery的Ajax实现

# 需求:通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面 # 模板 $.ajax({ url: '/add/', method: 'post', data:{'a':$("#first").val() ,'b':$("#second").val() }, success:function (data) { //成功触发 }, error:function (error) { //失败,触发 } }) # 默认情况下ajax会把{'a':$("#first").val() ,'b':$("#second").val() }数据转成 # 预处理数据 a=20&b=30,放到body体中 # 编码默认用urlencoded

Ajax---->服务器------>Ajax执行流程图

(三) 案例

1 通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面

# 视图函数 def index(request): return render(request, 'index.html') def add(request): # if request.is_ajax(): if request.method == 'POST': # 取出a和b a = int(request.POST.get('a')) b = int(request.POST.get('b')) print(a, b) # HttpResponse返回什么,js中的data就是什么 return HttpResponse(a + b) # js代码 // 借助jquery封装好的ajax方法,发送ajax请求 // 点击button按钮,触发Ajax请求 $('#btn').click(function () { $.ajax({ url: '/add/', // 向那个地址发送请求 method: 'post', // 发送请求类型 // 使用jQuery,获取输入框内的值 // 向后端传输的数据(没有指定编码,默认使用urlencoded) data: {'a': $('#first').val(), 'b': $('#second').val()}, // 数据正常返回,就会触发该匿名函数的执行,返回的数据就会赋值给data success: function (data) { console.log(data) // 把后端返回的数据,通过DOM操作,写到input框中 $('#result').val(data) }, // 请求失败,就会触发error的执行,并且会把错误信息给error error: function (error) { console.log(error) } }) }) # html代码 <input type="text" id="first"> + <input type="text" id="second"> = <input type="text" id="result"> <p><button id="btn">计算结果</button></p>

2 基于Ajax进行登录验证

用户在表单输入用户名与密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功,则跳转到首页,否则,在页面上显示相应的错误信息

# 视图函数 def auth(request): back_dic = {'user': None, 'message': None} name = request.POST.get('name') password = request.POST.get('password') print(name) print(password) user = models.User.objects.filter(name=name, password=password).first() print(user) # print(type(user)) if user: back_dic['user'] = user.name back_dic['message'] = '登录成功' else: back_dic['message'] = '用户名或密码错误' import json return HttpResponse(json.dumps(back_dic)) # js代码 $('#btn_json_hw02').click(function () { $.ajax({ url:'/auth/', method:'post', // jquery 从输入框中拿到数据,组成data,传输给后端去判断 data:{name:$('#hw_user').val(),password:$('#hw_pwd').val()}, // 数据正常返回,就会触发该匿名函数的执行,返回的数据就会赋值给data success:function (data) { // console.log(data) // console.log(typeof data) var data=JSON.parse(data) // 判断返回的数据中的内容 if (data.user){ location.href='http://www.baidu.com' //console.log(data.message) } else{ alert(data.message) } }, }) })

(四) Ajax文件上传

1 请求头ContentType的三种编码

(1) application/x-www-form-urlencoded

-最常见的 POST 提交数据的方式。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了): POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 user=lxx&age=2

(2) multipart/form-data

-又一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例: POST http://www.example.com HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="user" yuan ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA-- -这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。 -这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。 -上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。 -随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

(3) application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。 JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

2 基于Form表单上传文件

# 视图函数 def uploadfile(request): file = request.FILES.get('myfile') name = request.POST.get('name') # print(name) with open(file.name, 'wb') as f: for line in file: f.write(line) return HttpResponse('上传成功!') # html代码 <h1>通过form表单上传文件</h1> <form action="/uploadfile/" method="post" enctype="multipart/form-data"> <p><input type="file" name="myfile"></p> <p>用户名:<input type="text" name="name"></p> <input type="submit" value="提交"> </form>

3 基于Ajax上传文件

(1) 基于Ajax上传文件的模板

# 固定模板 var formdata=new FormData() formdata.append('myfile',$("#id_file")[0].files[0]) # 还可以带数据 $.ajax({ url:'/uploadfile/', method: 'post', //上传文件必须写这两句话 processData:false, # 预处理数据, contentType:false, # 不指定编码,如果不写contentType,默认用urlencoded data:formdata, # formdata内部指定了编码,并且自行处理数据 success:function (data) { console.log(data) } }) # 视图函数 def uploadfile(request): file = request.FILES.get('myfile') name = request.POST.get('name') # print(name) with open(file.name, 'wb') as f: for line in file: f.write(line) return HttpResponse('上传成功!') # js代码 // 借助jquery封装好的ajax方法,发送ajax请求 // 点击button按钮,触发Ajax请求 // ajax上传文件 $('#btn_file').click(function () { var formdata=new FormData() // 实例化得到一个formdata对象 // 把文件放到对象内 // formdata.append('myfile', 文件对象) formdata.append('myfile', $('#id_file')[0].files[0]) // formdata也可以存放数据 formdata.append('name', $('#id_name').val()) $.ajax({ url:"/uploadfile/", method:'post', // 上传文件必须写这两句话 processData:false, contentType:false, data:formdata, success:function (data) { alert(data) } }) }) # html代码 <h1>通过Ajax上传文件</h1> <p><input type="file" id="id_file"></p> <p>用户名:<input type="text" id="id_name"></p> <button id="btn_file">提交</button>

4 总结

-无论是使用Form表单上传文件,还是使用Ajax或者postman上传,后端的视图代码都不需要改变,只是改变前端部分的代码即可。Ajax异步请求,不用等待操作是否成功。

(五) Ajax提交json格式数据

​ 提交到服务器的数据都在 request.body 里,取出来自行处理。

$.ajax({ url:'/uploajson/', //写全,是什么样就写什么样 method:'post', contentType: 'application/json', //data要是json格式字符串 //data:'{"name":"","password":""}', //把字典转成json格式字符串 //JSON.stringify(dic) //把json格式字符串转成对象 //JSON.parse(data) data:JSON.stringify({name:$("#id_name1").val(),password:$("#id_password1").val()}), success:function (data) { //返回字符串类型,需要转成js的对象,字典 //1 如果:django 返回的是HttpResponse,data是json格式字符串,需要自行转成字典 //2 如果:django 返回的是JsonResponse,data是就是字典 //ajax这个方法做的是,如果响应数据是json格式,自动反序列化 console.log(typeof data) var res=JSON.parse(data) console.log(typeof res) console.log(res.status) console.log(res.msg) } }) # 视图函数 from django.http import JsonResponse def uploadjson(request): data = request.body print(data) dic = {'status': 100, 'msg': '成功'} print(request.POST) # 没有数据, import json return HttpResponse(json.dumps(dic)) # return JsonResponse(dic) # js代码 // 借助jquery封装好的ajax方法,发送ajax请求 // 点击button按钮,触发Ajax请求 // Ajax提交json格式数据 $('#btn_json').click(function () { $.ajax({ url:'/uploadjson/', method:'post', contentType:'application/json', // data如果是json格式字符串 // data:'{"name":"","password":""}' // 把字典转换成json格式字符串 // JSON.stringfy(dic) // 把json格式字符串转成对象 // JSON.parse(data) data:JSON.stringify({name:$('#id_name1').val(), password:$('#id_password1').val()}), success:function (data) { // 返回字符串类型,需要转成js的对象、字典 //1 如果:django 返回的是HttpResponse,data是json格式字符串,需要自行转成字典 //2 如果:django 返回的是JsonResponse,data是就是字典 //ajax这个方法做的是,如果响应数据是json格式,自动反序列化 console.log(data) console.log(typeof data) // var res = JSON.parse(data) // console.log(typeof res) // console.log(res.status) // console.log(res.msg) }, error:function (error) { console.log(error) }, }) }) # html代码 <h1>通过Ajax提交json格式数据</h1> <p>用户名:<input type="text" id="id_name1"></p> <p>密码:<input type="text" id="id_password1"></p> <button type="submit" id="btn_json">提交</button>

(六) 了解Django内置序列化器serializers

Django内置的serializers可以把对象序列化程json字符串

1 把对象转成json格式,json.dumps实现不了, 2 django内置了一个东西,可以把对象转成json格式 from django.core import serializers book_list = Book.objects.all() ret = serializers.serialize("json", book_list) # ret就是json格式字符串 """自己写,有局限,不通用 ll=[] for book in book_list: ll.append({'name':book.name,'price':book.pirce}) import json ret=json.dumps(ll) """ return HttpResponse(ret) # [{"model": "ajax_test.user", "pk": 1, "fields": {"name": "lxx", "password": "123"}}] # django内置的返回值,内容较多,需进一步处理
最新回复(0)