python学习:Django使用Ajax和序列化(7)
Django使用Ajax和序列化
Ajax可以在不刷新页面的情况下,局部更新页面数据。使用Ajax需要引入JQuery库,使用JQuery的Ajax。
下载JQuery库,http://www.jq22.com/jquery-info122
解压得到jquery-3.4.1.js和jquery-3.4.1.min.js,这两个js文件都可以使用,但是大小不同,一般开发时可以使用jquery-3.4.1.js,而正式项目使用jquery-3.4.1.min.js。
将解压得到的jquery-3.4.1.js拷贝到Django项目建立的静态资源文件夹statics。
使用Ajax步骤:
1、引入JQuery文件;
2、使用Ajax,Ajax格式:
$.ajax({
url : “”,
type:”POST”,
data:{“name”:“tang”,”pwd”,”123”},
success:function(arg){
//回调函数
}
})
示例:
新建一个ajax.html页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax使用</title>
<script>
//ajax的data是一个字典类型,键可以用'name',也可以直接name;但是value不能是字典,如果要传递字典值使用JSON.stringify()将字典值转换成字符串。
//设置traditional:true,传递键值可以是list
//设置dataType:'JSON',后端传来json字符串,arg自动变成对应对象,就可以不需要JSON.parse转换
function submit(){
var user = $("#user").val();
var pwd = $("#pwd").val();
var sel = $("#sel").val();
console.log(user,pwd,sel);
$.ajax({
url:"/url_dispatch/ajax1",
type:"GET",
data:{name:user,pwd:pwd,sel:sel},
traditional:true,
success:function(arg){
//回调函数
console.log(arg);
//后端传过来JSON字符串,转换成对象
var arg_obj = JSON.parse(arg);
alert(arg_obj.name)
//刷新页面
//window.location.reload();
}
});
}
</script>
</head>
<body>
<p><input type="text" id = "user" name="user"></p>
<p><input type="password" id = "pwd" name="pwd"></p>
<!--多选-->
<p>
<select id="sel" multiple>
<option value="1">选项1</option>
<option value="2">选项2</option>
<option value="3">选项3</option>
</select>
</p>
<p><input type="button" value="提交" onclick="submit()"></p>
<!--导入jquery-->
<script src="/static/jquery-3.4.1.js"></script>
</body>
</html>
修改urls.py文件,增加返回ajax.html的url,以及处理ajax请求的url
path("ajax/",views.ajax),
path("ajax1/",views.ajax1)
修改views.py,增加对应视图函数
#处理ajax请求
def ajax1(request):
#使用GET
# 可以获取到ajax传的数据data
#如果传入是value为列表,sel键会自动加上[],所以我们直接使用键获取不到值
#我们需要在ajax请求中加一个参数traditional:true
#<QueryDict: {'name': ['1'], 'pwd': ['ere2121'], 'sel[]': ['2', '3']}>
print(request.GET);
print(request.GET.get("name"))
print(request.GET.get("pwd"))
#getlist获取多个值
print(request.GET.getlist("sel"))
#后端返回一个json字符串
jsonDict = {"name":"tang","age":11,"addr":"chongqing"}
#使用json.dumps将对象转换成一个Json字符串
import json
jsonStr = json.dumps(jsonDict);
return HttpResponse(jsonStr)
#返回页面
def ajax(request):
return render(request,"ajax.html")
使用serialize(),直接将form表单的数据变成ajax传输数据。
在ajax.html中增加一个form表单,设置id
<form id="serialize_form">
name:<input type="text" name="name"></br>
age:<input type="number" name="age"></br>
</form>
<p><input type="button" value="提交form" onclick="submit1()"></p>
编写对应js代码,绑定点击事件响应:
function submit1(){
$.ajax({
url:"/url_dispatch/ajax2",
type:"GET",
data: $("#serialize_form").serialize(),
traditional:true,
success:function(arg){
//回调函数
console.log(arg);
}
});
}
修改urls.py,增加ajax跳转url路径
path("ajax2/", views.ajax2)
修改views.py,编写对应视图函数,获取form表单提交数据
#获取serialize()表单参数
def ajax2(request):
#<QueryDict: {'name': ['fdf'], 'age': ['1']}>
print(request.GET);
return HttpResponse("ok")
数据序列化
后端将数据序列化字符串格式,传入到前端,前端将数据反序列化,拿到数据渲染到页面上。
示例:
#序列化
from django.core import serializers
from helloApp.models import Book
import json
def ajax3_serial(request):
#返回数据
ret = {"status":False,"data":None}
#使用查询,book_list是一个querySet对象
try:
#查询出querySet,querySet中是对象
book_list = Book.objects.all();
# ret["data"] = book_list;
#使用serializer序列化book_list,变成字符串
# 这里相当于两次序列化,前端使用dataType:"JSON",arg是个对象,arg.data拿到字符串,然后使用JSON.parse(arg.data)再次反序列化,拿到对象列表
ret["data"] = serializers.serialize(book_list);
ret["status"] = True;
# #使用values查询的querySet中是字典
# book_list = Book.objects.values("name")
# #直接使用list(book_list)转化为一个list,就可以直接使用json.dump(ret)转换
# ret["data"] = list(book_list);
# ret["status"] = True;
except Exception as e:
ret["data"] = e
#直接使用json.dump(),不能序列化querySet
#将book_list变成字符串,就可以使用json.dump序列化
return HttpResponse(json.dump(ret))
#serializers不能序列化字典,可以序列化queryset
# return HttpResponse(serializers.serialize(ret));
Ajax补充
1、XMLHttpRequest,手动请求和jquery请求
如果不使用jQuery的Ajax提交请求,我们可以使用XMLHttpRequest对象,原生Ajax请求。
使用步骤:1、创建XMLHttpRequest对象;2、调用open(“method”,url),method为POST或者GET;3、编写回调方法onreadystatechange(),判断readyState == 4成功返回;4、send()方法调用请求
示例:
修改ajax.html,添加提交请求按钮,绑定事件
<!--
原生请求
不使用jquery提供的Ajax,实现Ajax提交
-->
<h1>原生提交GET请求</h1>
<p><button name="btn1" onclick="submit2()">GET提交</button></p>
<h1>原生提交POST请求</h1>
<p><button name="btn2" onclick="submit3()">POST提交</button></p>
编写对应js的方法
//GET提交
function submit2(){
//创建XMLHttpRequest对象
var xmlRequest = new XMLHttpRequest();
xmlRequest.open("GET",'/url_dispatch/ajax4?p = 12');
//回调函数
xmlRequest.onreadystatechange = function(){
if(xmlRequest.readyState == 4){
console.log(xmlRequest.responseText);
}
}
xmlRequest.send(null);
}
//POST提交
function submit3(){
//创建XMLHttpRequest对象
var xmlRequest = new XMLHttpRequest();
xmlRequest.open("POST",'/url_dispatch/ajax4/');
//回调函数
xmlRequest.onreadystatechange = function(){
if(xmlRequest.readyState == 4){
console.log(xmlRequest.responseText);
}
}
//post提交,要获取数据,需要设置请求头
xmlRequest.setRequestHeader("content-type","application/x-www-form-urlencoded;charset=UTF-8");
xmlRequest.send("p=12");
}
2、‘伪’Ajax
使用iframe和form伪造Ajax请求。Iframe和form通过form表单的target属性连接起来,让form表单的target等于iframe标签的name属性。
修改ajax.html,添加form和iframe标签
<!--iframe伪造请求
form配合iframe,form提交请求,iframe获取服务器返回数据,不刷新页面
iframe获取到数据,
-->
<h1>Iframe</h1>
<iframe id="iframe" name="ifr" onload="reloadIframe(this)"></iframe>
<form method="get" action="/url_dispatch/ajax4/" target="ifr">
<input type="text" name="test">
<input type="submit" value="提交">
</form>
编写处理iframe获取到数据库返回值的回调函数
//Iframe伪造回调函数
function reloadIframe(th){
//获取返回内容
console.log(th.contentWindow.document.body.innerHTML);
//使用jQuery获取内容
console.log($(th).contents().find("body").html());
}
3、Ajax上传文件
使用FormData对象,打包数据,将input框选择的文件打包,可以使用原生xmlHttpRequest.send(data)发送,也可以jQuery的ajax发送。
示例:
修改ajax.html,添加文件选择框input
<h1>formData文件上传</h1>
<input type="file" id="files">
<button onclick="submit4()">提交</button>
编写js代码获取数据,sumit4()方法
function submit4(){
//创建formData对象
var data = new FormData();
//将数据加入FormData
data.append("files",document.getElementById("files").files[0]);
$.ajax(){
url:"/url_dispatch/ajax4",
type:"GET",
data: data,
//使用FormData提交需要processData,contentType参数
processData:false,
contentType:false,
success:function(arg){
//回调函数
console.log(arg);
}
}
}
使用Iframe和Form表单上传文件。
示例:
修改ajax.html,增加上传文件form表单,和iframe标签。
<h1>Iframe文件上传</h1>
<iframe id="iframe1" name="ifr1"></iframe>
<form id="form1" method="post" action="/url_dispatch/ajax4/" enctype="multipart/form-data" target="ifr1">
<input type="file" name="files">
<button onclick="submit5()">提交</button>
</form>
增加js代码,提交表单
//回调函数,获取返回文件
function reloadIframe1(){
//获取返回内容
console.log(this.contentWindow.document.body.innerHTML);
//使用jQuery获取内容
console.log($(this).contents().find("body").html());
}
//使用Ifrme上传文件
function submit5(){
//绑定onload函数
document.getElementById("iframe1").onload = reloadIframe1;
//提交表单
document.getElementById("form1").submit();
}
4、跨域Ajax,JSONP
使用JSONP跨过同源策略。
示例:
修改ajax.html,jsonp实现过程其实是生成一个<script>块,指定src属性为远程url的标签,通过函数获取返回值。
<h1>Jsonp跨域访问</h1>
<!--浏览器有同源策略
XMLHttpRequest遵循策略,只能访问本服务器,不能获取其他服务器返回内容
JSONP越过浏览器同源策略
<img src="">可以是其他服务器的路径
<iframe src="">也可以是其他服务器路径
这些标签没有同源策略限制
-->
<button onclick="submit6()">提交</button>
编写js代码,ajax使用jsonp跨过同源策略限制,jsonp只能发送GET请求
//dataType:"jsonp"使用jsonp越过同源策略
//jsonpCallback指定回调处理函数
//服务器返回就是list()包裹数据,调用list(arg)函数,arg可以直接访问到返回内容
function submit6(){
$.ajax({
//url:"http://www.baidu.com",
url:"/url_dispatch/ajax4",
type:"GET",
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"list"
})
}
//回调函数
function list(arg){
console.log(arg)
}
修改对应url的视图函数返回字符串格式,必须使用:callback指定的名字(返回字符串)。
#不依赖jquery,使用Ajax
def ajax4(request):
# print(request.GET)
# print(request.POST)
# print(request.FILES)
# return HttpResponse("ok");
#同源策略跨过
#使用callback指定名字返回字符串
name = request.GET.get('callback')
print(name);
#jsonpCallback:"list",callback名字
#返回数据:指定callback的名字(返回数据)
return HttpResponse("%s('hello world')" %(name,))
#方式2
# #使用增加相应头,声明不使用同源策略
# obj = HttpResponse("hello world")
# obj["Access-Control-Allow-Origin"] = "*"
# return obj;
json序列化自定义类型
示例:
#json序列化自定义类型
import json
from datetime import datetime
#自定义json解释器,继承JSONEncoder
class MyJsonEncoder(json.JSONEncoder):
def default(self, o):
#是否是时间类型
if isinstance(o,datetime):
return o.strftime("%Y-%m-%d %H %M %S")
elif isinstance(o,c1):
return o.__dict__
else:
return json.JSONEncoder.default(self,o)
class c1:
def __init__(self,name,addr):
self.name = name
self.addr = addr
def say(self):
print("hello")
data_dict = {
"d1" : "112",
"d2" : datetime.now(),
"d3" : c1("lu","cq")
}
# c = c1("lu","cq")
# print(c.__dict__)
ret = json.dumps(data_dict,cls=MyJsonEncoder)
print(ret)
本文来自博客园,作者:渔歌晚唱,转载请注明原文链接:https://www.cnblogs.com/tangToms/articles/14158998.html