django08--前端jQuery的Ajax、自带序列化组件
1 Ajax介绍
# Ajax Asynchronous Javascript And XML
异步提交
局部刷新
eg:github注册
动态获取用户名实时的跟后端确认并实时展示的前端(局部刷新)
# 1.翻译成中文就是“异步的Javascript和XML”
即:使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)
# 2.不是新的编程语言,而是一种使用现有标准的新方法
# 3.最大的优点是
在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
这一特点给用户的感受是在不知不觉中完成请求和响应过程
# 4.不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
Ajax我们只学习jQuery封装之后的版本(不学原生的 原生的复杂并且在实际项目中也一般不用)
所以我们在前端页面使用ajax的时候需要确保导入了jQuery
ps:并不只有jQuery能够实现ajax,其他的框架也可以 但是换汤不换药 原理是一样的
1.1 基本格式
$.ajax({
// 1.指定朝哪个后端发送ajax请求
url:'', // 不写就是朝当前地址提交
// 2.请求方式
type:'post', // 不指定默认就是get 都是小写
// 3.数据
data:{'username':'jason','password':123} # 在Python,是字典;在前端:是自定义对象
// 4.请求数据的编码格式
contentType:'application/json',
// 5.响应数据的格式 自动反序列化
dataType:'json', // 以后推荐加上 增加程序兼容性
// 6.异步回调函数:当后端给你返回结果的时候会自动触发 args接受后端的返回结果
success:function (args) {
console.log(typeof args)
}
})
# 前后端交互,数据是JSON时
# 后端返回Json格式
采用 JsonResponse 返回 或 利用json模块序列化后,再HttpResponse返回
# 前端接受:
1.后端用JsonResponse返回
前端回调函数 会自动反序列化成 json对应的格式
2.后端用HttpResponse返回
回调函数不会自动帮你反序列化,指定参数 或 手动反序列化
1.手动反序列化 JSON.parse()
2.在ajax里面配置一个参数
dataType:'json'
1.2 小例子
"""
页面上有三个input框
在前两个框中输入数字 点击按钮 朝后端发送ajax请求
后端计算出结果 再返回给前端动态展示的到第三个input框中
(整个过程页面不准有刷新,也不能在前端计算)
"""
##### my_ajax.html
<input type="text" id="i1">+<input type="text" id="i2">=<input type="text" id="i3">
<button id="btn">提交</button>
<script>
$('#btn').click(function () {
// 朝后端发送ajax请求
$.ajax({
// 1.指定朝哪个后端发送ajax请求
url:'', // 不写就是朝当前地址提交
// 2.请求方式
type:'post', // 不指定默认就是get 都是小写
// 3.数据
# data:{'username':'jason','password':123} # 在Python,是字典;在前端:是自定义对象
data:{'i1':$('#i1').val(),'i2':$('#i2').val()},
// 4.回调函数:当后端给你返回结果的时候会自动触发 args接受后端的返回结果
success:function (args) {
{#alert(args) // 通过DOM操作动态渲染到第三个input里面#}
{#$('#d3').val(args)#}
console.log(typeof args)
}
})
})
</script>
##### views.py
from django.shortcuts import render,HttpResponse
import json
from django.http import JsonResponse
def ab_ajax(request):
if request.method == "POST":
# print(request.POST) # <QueryDict: {'username': ['jason'], 'password': ['123']}>
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
# 先转成整型再加
i3 = int(i1) + int(i2)
# print(i3)
d = {'code':100,'msg':i3}
return HttpResponse(json.dumps(d))
# return JsonResponse(d)
return render(request,'index.html')
2 前后端传输数据的编码格式
前后端传输数据的时候,一定要确保 编码格式 跟 数据真正的格式 是一致的
# 前提:
# 1.可以发送网络请求的标签
1.浏览器地址栏直接输入url回车 GET请求
2.a标签href属性 GET请求
3.form表单 GET请求/POST请求
4.ajax GET请求/POST请求
# 2.get请求的数据: 直接放在url后面的 编码格式 由 url编码决定
eg: url?username=jason&password=123
# 3.post请求的数据: 存放请求体中 编码格式 由 content-Type决定 (学习这个)
# 4.可以朝后端发送post请求的方式
form表单 和 ajax请求
# 前后端传输数据的编码格式: content-Type
content-Type在请求头中,用于标识数据的编码格式
后端通过该参数的不同 采取对应的处理措施 来操作数据
# 具体格式:
urlencoded
formdata
json
# 前端查看content-Type:
浏览器--F12--network--name(最新的页面请求)--Headers--Request Headers--content-type:具体格式
3 form表单发送数据
# form表单+post请求 发送不同格式的数据
# 1.urlencoded 默认的数据编码格式
# 指定编码格式
enctype="application/x-www-form-urlencoded"
# 数据格式
键值对 eg:username=jason&password=123
# 后端获取:request.POST中
django后端针对符合urlencoded编码格式的数据 自动解析封装到request.POST中
# 2.form-data
# 指定编码格式
enctype="multipart/form-data"
# 数据格式
键值对 和 文件
# 后端获取:
键值对 :request.POST中
文件 :request.FILES中
# 3.json
form表单无法发送json格式数据
4 Ajax发送数据
4.1 ajax发送urlencoded格式数据
# urlencoded 默认的数据编码格式
# 指定编码格式
参数 contentType 不用指定
# 数据格式
键值对 eg:username=jason&password=123
# 后端获取:request.POST
4.2 ajax发送json格式数据
# 前提
python中序列化反序列化
import json
json.dumps() python --> json
json.loads() json --> python
# json.loads括号内 参数 默认为json格式
但如果传入了一个二进制格式的数据 内部会自动解码 再反序列化
Js中序列化反序列化
JSON.stringify() js --> json
JSON.parse() json --> js
# json格式
# 指定编码格式
contentType='application/json'
# 后端获取:request.body中 二进制形式
django针对接受的json格式的数据 不会做任何的处理,以二进制的形式在request.body中
# request对象方法补充
request.is_ajax() # 判断当前请求是否是ajax请求 返回布尔值
# 总结:
1.contentType参数指定成:application/json
2.数据是真正的json格式数据
3.django后端不会处理json格式数据 需要手动去request.body获取并处理
# eg:
<script>
$('#d1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'username':'jason','age':25}), // 前端编译成json格式
contentType:'application/json', // Ajax向后端发送数据的编码格式
success:function () {
}
})
})
</script>
def ab_json(request):
if request.is_ajax():
if request.method == 'POST':
json_bytes = request.body
json_str = json_bytes.decode('utf-8')
json_dict = json.loads(json_str)
# json.loads括号内 如果传入了一个二进制格式的数据 那么内部自动解码再反序列化
json_dict = json.loads(json_bytes)
print(json_dict)
return render(request,'ab_json.html')
4.3 ajax发送文件(fromdata)
# ajax发送文件
需要借助于js内置对象FormData
# 总结:
1.需要利用内置对象FormData
// 1 需要先实例化一个FormData内置对象
let formDateObj = new FormData();
// 2 添加普通的键值对
formDateObj.append('username',$('#d1').val());
formDateObj.append('password',$('#d2').val());
// 3 添加文件对象
formDateObj.append('myfile',$('#d3')[0].files[0])
2.需要指定两个关键性的参数
contentType:false, // 不需使用任何编码 django后端能够自动识别formdata对象
processData:false, // 告诉你的浏览器 不要对你的数据进行任何处理
3.后端获取:
键值对 :request.POST中
文件 :request.FILES中
<script>
// 点击按钮朝后端发送普通键值对和文件数据
$('#d4').on('click',function () {
// 1 需要先实例化一个FormData内置对象
let formDateObj = new FormData();
// 2 添加普通的键值对
formDateObj.append('username',$('#d1').val());
formDateObj.append('password',$('#d2').val());
// 3 添加文件对象
formDateObj.append('myfile',$('#d3')[0].files[0])
// $('#d3')--js标签对象集合 [0]--具体的js标签对象 .files[0]--再其具体的文件对象
// 4 将对象基于ajax发送给后端
$.ajax({
url:'',
type:'post',
data:formDateObj, // 直接将对象放在data后面即可
// ajax发送文件必须要指定的两个参数
contentType:false, // 不需使用任何编码 django后端能够自动识别formdata对象
processData:false, // 告诉你的浏览器不要对你的数据进行任何处理
//原因:默认情况下jQuery会将数据预处理成username=jason&age=20格式
success:function (args) {
}
})
})
</script>
def ab_file(request):
if request.is_ajax():
if request.method == 'POST':
print(request.POST)
print(request.FILES)
return render(request,'ab_file.html')
5 自带的序列化组件(了解)
# Django内置的serializers
但实际开发中,Django 用的序列化组件是 drf
# 需求:在前端给我获取到后端用户表里面所有的数据(json格式) 并且要是列表套字典:[{},{},{},{},{}]
import json
from django.http import JsonResponse
from django.core import serializers # 自带的序列化模块
def ab_ser(request):
user_queryset = models.User.objects.all()
# 方式一:用Django模板语法,前端自己写for循环获取
return render(request,'ab_ser.html',locals())
"""
[ { % for user_obj in user_queryset %}
{ {{user_obj}} }
{ % endfor %} ]
"""
# 但若是前后端是分离的,方式一就不可行了,前端不能使用Django的模板语法!
# 方式二:自己构建数据样式,再利用JsonResponse 返回json对象
# 构建特定样式的json数据:[{},{},{},{},{}]
user_list = []
for user_obj in user_queryset:
tmp = {
'pk':user_obj.pk,
'username':user_obj.username,
'age':user_obj.age,
'gender':user_obj.get_gender_display()
}
user_list.append(tmp)
return JsonResponse(user_list,safe=False)
# 注意:safe参数,因为JsonResponse 正常只能序列化字典,其他可迭代对象,要设置该参数为False
"""
方式二的结果:
[
{"pk": 1, "username": "jason", "age": 25, "gender": "male"},
{"pk": 2, "username": "egon", "age": 31, "gender": "female"},
{"pk": 3, "username": "kevin", "age": 32, "gender": "others"},
{"pk": 4, "username": "tank", "age": 40, "gender": 4}
]
"""
# 但若是数据字段比较多时,自己来构建数据样式就不合理!
# 方式三:Django后端提供序列化模块 serializers
# 会自动帮你将数据变成json格式的字符串 并且内部非常的全面
res = serializers.serialize('json',user_queryset)
return HttpResponse(res)
"""
方式三的结果:
[
{ "model": "app01.user",
"pk": 1,
"fields": {"username": "jason", "age": 25, "gender": 1}},
{ "model": "app01.user",
"pk": 2,
"fields": {"username": "egon", "age": 31, "gender": 2}},
{ "model": "app01.user",
"pk": 3,
"fields": {"username": "kevin", "age": 32, "gender": 3}},
{ "model": "app01.user",
"pk": 4,
"fields": {"username": "tank", "age": 40, "gender": 4}}
]
"""
# 总结:
前后端分离的项目
作为后端开发的你只需要写代码将数据处理好 能够json序列化返回给前端即可
再写一个接口文档 告诉前端每个字段代表的意思即可
写接口就是利用序列化组件渲染数据,然后写一个接口文档 该交代的交代一下就完事
6 ajax结合sweetalert
"""
自己要学会如何拷贝
学会基于别人的基础之上做修改 --sweetalert 弹出框插件
研究各个参数表示的意思 然后找葫芦画瓢
"""
# eg:ajax结合sweetalert 二次确认删除
<script>
$('.del').on('click',function () {
// 先将当前标签对象存储起来
let currentBtn = $(this);
// 二次确认弹框
swal({
title: "你确定要删吗?",
text: "你可要考虑清除哦,可能需要拎包跑路哦!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "是的,老子就要删!",
cancelButtonText: "算了,算了!",
closeOnConfirm: false,
closeOnCancel: false,
showLoaderOnConfirm: true
},
function(isConfirm) {
if (isConfirm) {
// 朝后端发送ajax请求删除数据之后 再弹下面的提示框
$.ajax({
{#url:'/delete/user/' + currentBtn.attr('delete_id'), // 1 传递主键值方式1 直接放在URL上#}
url:'/delete/user/', // 2 放在请求体里面
type:'post',
data:{'delete_id':currentBtn.attr('delete_id')},
success:function (args) { // args = {'code':'','msg':''}
// 判断响应状态码 然后做不同的处理
if(args.code === 1000){
swal("删了!", args.msg, "success");
// 更新当前的用户展示页面
// 1.lowb版本 直接刷新当前页面
{#window.location.reload()#}
// 2.利用DOM操作 动态刷新 -- 直接将当前的数据行进行删除
currentBtn.parent().parent().remove()
}
else{
swal('完了','出现了未知的错误','info')
}
}
})
}
else {
swal("怂逼", "不要说我认识你", "error");
}
});
})
</script>

浙公网安备 33010602011771号