Django接收axios传JSON后重定向报NoneType错误的解决方法
问题背景
- 现有
cat1.html模板用于展示商品列表,用户选中商品时会生成包含所选商品属性的对象 - 点击「加入购物车」按钮时,axios会将经过
JSON.stringify处理的商品对象作为参数,向/cart路由发起请求
前端对应代码:
ulElement.addEventListener('click', function(event) { let targetClasses = Array.from(event.target.classList); if(targetClasses.includes('dropdown-item')) { /* code to build the item */ } if(targetClasses.includes('btn-cart')) { axios.get('/cart', { params: { item: JSON.stringify(item) } } ); } });
- 加购请求本身可以正常传输数据,服务端能正常打印接收到的商品对象,原有后端代码如下:
def cart(request): item_dict = json.loads(request.GET.get('item')) user_cart.append(item_dict) print(user_cart); # 这行运行正常 # return redirect('cart') 执行该行会抛出TypeError
- 尝试添加重定向到购物车视图的逻辑时触发异常,错误信息如下:
the JSON object must be str, bytes or bytearray, not NoneType
- 先后尝试过
window.location.href前端跳转、按钮包裹<a href="/cart"></a>标签的方案,均触发相同错误。
问题根因
你把两个完全不同的逻辑塞到了同一个/cart路由对应的视图里:
- 逻辑1:接收前端传的商品参数,把商品加入购物车(需要请求携带item参数)
- 逻辑2:渲染/跳转购物车页面(不需要任何商品参数)
不管你用什么方式跳转,只要是跳转到/cart,发起的都是不带item参数的普通GET请求,这时候request.GET.get('item')拿到的是None,传给json.loads自然会报类型错误。你之前试的前端跳转、a标签方案都是直接触发无参数请求,根本没解决「同一个视图既要读参数又要渲染页面」的核心问题,当然会报错。
修复方案
1. 拆分后端路由和视图
把加购物车和展示购物车的逻辑拆成两个独立接口,不要混在一起:
- 新增一个专门处理加购物车的路由,比如
/add-cart,只负责接收商品数据、写入购物车,返回JSON格式的成功响应即可,不要在这个接口里做重定向 - 原
/cart路由只负责渲染购物车页面,删掉里面解析item参数的代码
参考后端代码:
import json from django.http import JsonResponse from django.shortcuts import render # 加购物车接口 def add_cart(request): item_str = request.GET.get('item') if item_str: item_dict = json.loads(item_str) user_cart.append(item_dict) return JsonResponse({"status": "success"}) # 购物车页面接口 def cart(request): # 这里只需要把购物车数据传给模板渲染,不需要处理任何加购参数 return render(request, 'cart.html', {"cart_items": user_cart})
记得在路由配置文件里把两个路径分别绑定到对应视图函数。
2. 修改前端交互逻辑
axios请求改到新加的/add-cart接口,等接口返回加购成功的响应后,在前端用JS跳转到购物车页面,不要靠后端重定向:
ulElement.addEventListener('click', async function(event) { let targetClasses = Array.from(event.target.classList); if(targetClasses.includes('dropdown-item')) { /* 原有构造商品对象的逻辑保持不变 */ } if(targetClasses.includes('btn-cart')) { // 发请求完成加购 await axios.get('/add-cart', { params: { item: JSON.stringify(item) } } ); // 加购完成后前端跳转到购物车页 window.location.href = '/cart'; } });
额外说明
用GET请求做数据写入本身不符合HTTP规范,后续如果要优化可以把加购物车的接口改成POST请求,能避免很多重复提交的问题。
内容的提问来源于stack exchange,提问作者manzosk3
相关产品推荐
相关产品推荐

