Axios传数组至Django后端被拆分?求解决方法
前端Axios传递数组到Django后端的问题与解决
问题场景
前端通过Axios向Django后端发送包含数组的请求,具体情况如下:
- 前端准备的
details数组格式:
[{ nameDetail: "1", valueDetail: "3" }, { nameDetail: "2", valueDetail: "4" }]
- 传给Axios前
console.log的输出:
Array(2) 0: {nameDetail: 'Size', valueDetail: '2oz'}, 1: {nameDetail: 'Color', valueDetail: 'White'}, length: 2, [[Prototype]]: Array(0)
- Axios请求代码:
const { data } = await axios.post( `http://localhost:8000/api/products/product/add/`, { name: name, brand: brand, category: category, description: description, badge: badge, price: price, discount: discount, countInStock: countInStock, images: images, details: details, // 存在问题的字段 }, { headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${userLogin.token}`, }, } )
- 后端
views.py中print(request.data)的结果:
<QueryDict: {'name': ['Electronic'], 'brand': ['ez'], 'category': ['Juices'], 'description': ['azea'], 'badge': ['promos'], 'price': ['22'], 'discount': ['2'], 'countInStock': ['2'], 'details[0][nameDetail]': ['Size'], 'details[0][valueDetail]': ['2oz'], 'details[1][nameDetail]': ['Color'], 'details[1][valueDetail]': ['White'], 'images[]': [<InMemoryUploadedFile: S33ef534d442d4a1d82ce7f52821f391aX (1).webp (image/webp)>]}>
问题原因
因为请求使用了multipart/form-data头,这种格式原本是为表单数据设计的,它会自动把嵌套对象、数组拆解成key[subkey]或array[index][key]的扁平键值对结构,这是该格式处理复杂数据的默认行为,所以后端收到的details会被拆分成零散的字段。
解决方法
方法一:后端解析扁平QueryDict
直接在Django后端将拆解后的键值对重新组装成数组:
# views.py中处理details的代码 details = [] # 遍历QueryDict提取details相关字段 for key, value in request.data.items(): if key.startswith('details['): # 解析索引和字段名,例如details[0][nameDetail] -> 索引0,字段nameDetail parts = key.split('[') index = int(parts[1].replace(']', '')) field = parts[2].replace(']', '') # 确保数组长度足够容纳当前索引 while len(details) <= index: details.append({}) # 给对应索引的对象赋值(QueryDict的值是数组,取第一个元素) details[index][field] = value[0] # 循环处理组装好的数组 for item in details: print(item['nameDetail'], item['valueDetail'])
方法二:改用JSON格式传递数据(适配文件上传)
如果想要保留数组的原始结构,可以将非文件数据转为JSON字符串,文件单独处理:
前端修改:
const formData = new FormData(); // 添加普通字段 formData.append('name', name); formData.append('brand', brand); // ...其余普通字段同理 // 将details转为JSON字符串后添加 formData.append('details', JSON.stringify(details)); // 添加上传的文件 images.forEach(image => { formData.append('images', image); }); const { data } = await axios.post( `http://localhost:8000/api/products/product/add/`, formData, { headers: { Authorization: `Bearer ${userLogin.token}`, }, } )
后端修改:
# views.py中解析数据 import json # 解析details的JSON字符串为数组 details_json = request.data.get('details') details = json.loads(details_json) # 循环处理数组 for item in details: print(item['nameDetail'], item['valueDetail']) # 从request.FILES获取上传的文件 images = request.FILES.getlist('images')
内容的提问来源于stack exchange,提问作者Mohamed Mhiri
相关产品推荐
相关产品推荐

