JS传递字典至Django视图获QueryDict,如何还原可操作对象?
解决JS发送字典到Django视图后结构不一致的问题
问题原因
jQuery的$.ajax默认会把JavaScript对象序列化为表单格式(application/x-www-form-urlencoded),导致Django收到的QueryDict是扁平结构,无法直接对应原字典的嵌套层级;且len(request.POST)会包含csrf令牌和所有扁平后的键,无法得到真实的元素数量。
方案1:发送JSON格式数据(推荐)
直接将数据序列化为JSON字符串发送,后端解析后即可得到与原结构一致的Python字典。
前端JS修改
function sendData(event){ const res = { 0:{"val1": 1, "val2":2}, 1:{"val1": 3, "val2":4}} // 获取页面中的CSRF令牌 const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; $.ajax({ url: '/your-view-url/', // 替换为你的视图路由 method: 'POST', data: JSON.stringify({ result: res }), // 将对象转为JSON字符串 contentType: 'application/json', // 指定请求内容类型为JSON headers: { 'X-CSRFToken': csrftoken // 携带CSRF令牌 }, dataType: "json", success: function(response) { // 处理成功响应 } }) }
后端Django视图处理
import json from django.http import JsonResponse def view1(request): if request.method == 'POST': # 从请求体读取并解析JSON数据 data = json.loads(request.body) result_dict = data.get('result', {}) # 循环处理每个元素并存入数据库 for idx, item in result_dict.items(): val1 = item.get('val1') val2 = item.get('val2') # 示例:存入数据库 # YourModel.objects.create(val1=val1, val2=val2) return JsonResponse({'status': 'success'})
方案2:解析扁平QueryDict为嵌套字典(不修改前端时使用)
如果不想改动前端代码,可以手动解析QueryDict的扁平键,还原为嵌套结构。
def view1(request): post_data = request.POST.dict() result_dict = {} # 遍历所有键,提取result下的嵌套结构 for key, value in post_data.items(): if key.startswith('result['): # 解析键路径,如"result[0][val1]"拆分为["0", "val1"] key_parts = key.replace('result[', '').replace(']', '').split('][') idx = key_parts[0] field = key_parts[1] if idx not in result_dict: result_dict[idx] = {} result_dict[idx][field] = value # 此时result_dict结构与原JS字典一致,可循环操作 for idx, item in result_dict.items(): val1 = item['val1'] val2 = item['val2'] # 执行数据库存储操作 return JsonResponse({'status': 'success'})
说明
- 方案1更简洁高效,能完全保留原数据结构,避免手动解析的繁琐,优先推荐。
- 原
len(request.POST)为5是因为包含了1个csrf令牌键和4个扁平后的result子键,并非真实的元素数量(实际是2个)。
内容的提问来源于stack exchange,提问作者problème0123
相关产品推荐
相关产品推荐

