jQuery Ajax POST传字典到Django视图时数据始终为空问题
问题原因
- 按钮默认行为中断AJAX请求:
<button>标签未设置合法type值时,默认type为submit,如果按钮放在表单容器内,点击后会优先触发表单原生提交跳转,直接中断JS中编写的AJAX请求。你代码中写的type="ajax-call"不是标准按钮属性值,无法覆盖默认提交行为,最终后端收到的是原生表单提交的空请求,自然拿不到JS组装的参数。 - 视图未区分请求方法:当前
sondage视图同时处理页面初次加载的GET请求和AJAX POST请求,代码中没有加请求方法判断,页面首次打开走GET请求时request.POST本身就是空字典,必然触发"AJAX PROBLEME"的打印逻辑。 - AJAX配置与后端返回格式不匹配:
$.ajax中的dataType: "json"参数作用是告知jQuery"后端将返回JSON格式数据",但你的后端代码最终返回的是render渲染的HTML页面,不是JSON格式,jQuery会判定响应解析失败,可能导致请求流程异常中断。 - 潜在变量问题:如果JS中
heure/jour等待提交变量存在未定义、取值为undefined的情况,也会导致提交的参数异常。
修复方案
前端部分
- 修正按钮type属性,阻断原生表单提交:
<div> <button class="button" type="button" onclick="getValue();">Envoyer</button> </div>
如果不想修改按钮属性,也可以在
getValue函数第一行添加event.preventDefault();,手动阻止默认提交行为。
- 调整AJAX请求配置,补全结果回调,确保参数正常发送:
<script type="text/javascript"> function getValue(){ // 注意:此处要确保heure、jour等所有待提交变量都已正确赋值,不存在undefined情况 $.ajax({ url: "{% url 'sondage' %}", type : 'POST', // 后端如果返回JSON就保留该行,返回HTML就直接删除 dataType: "json", data: { heure_reponse: heure, jour_reponse: jour, habitude_reponse: habit, faim_reponse : faim, soif_reponse: soif, estomac_reponse: estomac, miam_reponse: miam, quantite_reponse: quantite, but_reponse: but, adresse_reponse: adresse, identifiant_reponse: identifiant } }).done(function(res){ console.log("提交成功", res); // 此处编写提交成功后的页面交互逻辑 }).fail(function(err){ console.log("提交失败", err); }) } </script>
后端部分
- 增加请求方法判断,分开处理页面渲染和AJAX提交逻辑,AJAX请求直接返回JSON格式响应,和前端配置匹配。
- 移除冗余的文件关闭代码(
with语句会自动关闭操作的文件),补全目录存在性判断避免写入报错。
from django.contrib.auth.decorators import login_required from django.views.decorators.csrf import csrf_exempt from django.shortcuts import render from django.http import JsonResponse from csv import writer, QUOTE_MINIMAL import os @csrf_exempt @login_required def sondage(request): # 单独处理POST提交逻辑 if request.method == "POST": reponses = list(request.POST.items()) if len(reponses) == 0: print("AJAX PROBLEME") return JsonResponse({"code": 500, "msg": "参数获取失败"}) user_identifier = request.user.get_filename().split('/')[1].split('.')[0] reponses.append(user_identifier) write_csv(reponses, user_identifier) return JsonResponse({"code": 200, "msg": "提交成功", "data": reponses}) # GET请求正常渲染页面 return render(request, 'sondage.html') def write_csv(data,name): # 自动创建不存在的目录,避免路径报错 os.makedirs('uploads/questionnaire/', exist_ok=True) with open('uploads/questionnaire/sondage.csv', 'a', newline='', encoding="utf-8") as csvfile: csv_writer = writer(csvfile, delimiter=',', quoting=QUOTE_MINIMAL) csv_writer.writerow(data)
内容的提问来源于stack exchange,提问作者Alexandre RODRIGUEZ
相关产品推荐
相关产品推荐

