如何在Django的views.py中访问AJAX调用发送的数据
下面是我在HTML中使用的代码,用来发送一个用户ID的数组(这些ID是数字)。当我点击复选框时,就会发送这个数组(checkIds):
var checkIds = []
$(document).on("click","#group_save",function(){
$("#candidate-data tr").each(function(index,rowhtml){
var checked= $('input[id="groups"]:checked',rowhtml).length;
checkIds = jQuery.unique(checkIds)
if (checked==1){
checkIds.push($('.hideMe',rowhtml).text());
}
});
alert(checkIds);
var jsonText = JSON.stringify(checkIds)
checkIds.length = 0;
var groupName = $('input:text[name="group_name"]').val();
alert(groupName)
$.ajax({
url: "{% url 'userinfo:groups' %}" + "?gname="+groupName,
type: "POST",
data:jsonText,
dataType: 'json',
success: function(){
notyfy({type: "success", layout: "topCenter", text: "Saved", timeout: 5000});
}
});
});
我该如何在我的views.py中访问data:jsonText
?我现在的做法是这样,但没有成功。我需要把gname
(名字)和数组(jsonText
)的ID一起保存到两个表格中:Groups和GroupMembers。在Groups表中,我需要保存组名(gname),然后在保存之后,我需要获取保存的组对象的ID,并把这个ID和用户ID数组(jsonText)一起保存到GroupMembers表中:
def groups(request):
gname = request.GET.get('gname', None)
if request.method == 'POST':
Groups(name=gname).save()
usersV = request.POST.get('jsonText')
x = request.GET.get('id',None)
print x
if x != "0":
for users in usersV:
print users
GroupMembers(group_id=x,user_id=users).save()
return HttpResponse("Success")
else:
return HttpResponse("Error")
4 个回答
request.POST
是用来处理表单提交的数据的字典。你现在发送的不是这些数据,而是一个完整的 JSON 数据块。你可以使用 request.body
来获取这个 JSON 数据,然后把它解析成一个 Python 字典。
usersV = json.loads(request.body)
jsonText
是你在 JavaScript 文件中用来表示 JSON 的变量名。它并不是 JSON 结构中某个数据的键名。在下面的代码行中,把 jsonText
替换成实际的键名。
request.POST.get('jsonText')
你可以使用以下内容:
var checkIds = [];
$(document).on("click","#group_save",function(){
$("#candidate-data tr").each(function(index,rowhtml){
var checked= $('input[id="groups"]:checked',rowhtml).length;
checkIds = jQuery.unique(checkIds)
if (checked==1){
checkIds.push($('.hideMe',rowhtml).text());
}
});
var groupName = $('input:text[name="group_name"]').val();
$.ajax({
url: "{% url 'userinfo:groups' %}",
type: "POST",
data: {
"gname": gname,
"checkids": checkIds.slice(0)
},
dataType: 'json',
traditional: true,
success: function(){
notyfy({
type: "success",
layout: "topCenter",
text: "Saved",
timeout: 5000
});
}
});
checkIds.length = 0;
});
然后在你的 Python 代码中只需使用:
request.POST.get('gname');
request.POST.getlist('checkids');
简单解释一下
首先,jQuery 会帮你处理数据对象的转换,所以其实没必要用 JSON.stringify
或其他方法去预处理,除非你要发送一个非常特定的格式到服务器。通过设置 traditional: true
,你是在告诉 jQuery 用以下格式来转换你的数组参数:
checkids=value&checkids=value&checkids=value
而不是:
checkids[]=value&checkids[]=value&checkids[]=value
这个在 这里 和 这里 解释得很清楚,简单来说,Python/Django 默认支持“非方括号”形式的参数序列化,可以直接用 .getlist()
。
哦,还有 checkIds.slice(0)
的原因(这会创建一个数组的副本),是因为你后面会设置 checkIds.length = 0;
,我心里有点担心,如果 Ajax 调用在后面的执行周期中触发,直接引用的数组可能会变空,而副本就不会。这种情况极不可能发生,因为 Ajax 调用应该在请求时立即触发,但我在处理像 jQuery 这样的黑箱或库时总是比较谨慎……不过你不必过于担心我的这种谨慎,实际上可以安全地使用:
data: {
"gname": gname,
"checkids": checkIds
},
这个方法对我有效:
var checkIds = [];
$(document).on("click","#group_save",function(){
$("#candidate-data tr").each(function(index,rowhtml){
var checked= $('input[id="groups"]:checked',rowhtml).length;
checkIds = jQuery.unique(checkIds)
if (checked==1){
checkIds.push($('.hideMe',rowhtml).text());
}
});
alert(checkIds);
var groupName = $('input:text[name="group_name"]').val();
alert(groupName);
$.ajax({
url: "{% url 'userinfo:groups' %}" + "?gname="+groupName+"&checkids="+checkIds,
type: "POST",
dataType: 'json',
traditional: true,
success: function(){
notyfy({type: "success", layout: "topCenter", text: "Saved", timeout: 5000});
}
});
checkIds.length = 0;
然后在你的 views.py 文件里:
def groups(request):
print request.GET.copy()
gname = request.GET.get('gname', None)
if request.method == 'POST':
g = Groups(name=gname)
g.save()
x = g.pk
userlist = request.GET.get('checkids')
for users in userlist:
print users
GroupMembers(group_id=x, user_id=users).save()
return HttpResponse("Success")
else:
return HttpResponse("Error")