1-Django - AJAX
traditional参数(坑!!!)
Ajax在请求时,有个默认参数traditional,值是false。这玩意是个坑,我们来说道说道。
Ajax在提交数据时,会使用jQuery.param( obj, traditional )该方法进行处理数据,也就是所谓的深度序列化。这个特性说是jQuery1.4以后才有的,1.4之前没有,我也没确认,无所谓,知道如何处理就好了。
来看现象。
主要是对数据组的处理:
# 当`traditional:false`时,如果你的请求体中包含这样的数组
# data:{hobby: ["1", "2"]}
# 经过序列化后,会处理成这样再提交: 'hobby[]="1"&hobby[]="2"' ,那么提交到Django后端后
# 坏事了:你接收的是这样的 'hobby[]': ['1', '2']
# 这就有点麻烦了,所以,前端怎么深度序列化我们不管,我只希望后端接收的是这样的数据:'hobby': ['1', '2']
# 那怎么搞呢?
# 当`traditional:true`时,对于数组data:{hobby: ["1", "2"]}的处理
# 会处理成这样再提交 'hobby="1"&hobby="2"'
# 那么后端接收的值就是这样的: 'hobby': ['1', '2']
# 这样的话,我们就可以通过下面的代码取值了,注意是getlist
# hobby_list = request.POST.getlist("hobby")
print(hobby_list) # ['1', '2']
那么当traditional:true
时,让Ajax处理数据时,数组不让其深度序列化。
来个示例:
urls.py
:
from django.contrib import admin
from django.urls import path
from api.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path('index/', index),
]
views.py
:
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
if request.method == "GET":
return render(request, 'index.html')
data = request.POST
print(data) # <QueryDict: {'user': ['zhangkai'], 'hobby': ['1', '2'], 'csrfmiddlewaretoken': ['vjK42nJAucCPIVd81WY1PTJeTkBBNi9efLzyZC24zuG4MX2fdUUUuMR0jfRdmpOt']}>
user = request.POST.get("user")
print(user) # zhangkai
hobby_list = request.POST.getlist("hobby")
print(hobby_list) # ['1', '2']
return HttpResponse("OK")
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<input type="text" name="user" placeholder="user" class="form-control">
<input type="checkbox" name="hobby" value="1"> 吸烟
<input type="checkbox" name="hobby" value="2"> 喝酒
<input type="checkbox" name="hobby" value="3"> 烫头
<input type="button" id="btn" value="提交">
</form>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<script>
$("#btn").click(function () {
let arr = []
$("input[name=hobby]:checked").each(function () {
arr.push($(this).val())
})
console.log(arr)
$.ajax({
url: "/index/",
type: "post",
traditional: true, // 就这个家伙要多注意
data: {
"user": $("input[name=user]").val(),
"hobby": arr,
"csrfmiddlewaretoken": $("[name='csrfmiddlewaretoken']").val()
}, success: function (res) {
console.log(res)
}
})
})
</script>
</html>
参考: