Django无登录购物车:会话密钥不一致,API返回空数组
无登录购物车Session不一致问题
我正在实现无需用户登录的购物车功能,依赖Session密钥标识用户,但每次添加商品到购物车时都会获取到不同的Session密钥。Django管理后台能看到购物车数据已成功添加,但调用获取购物车的API时始终返回空数组。相关代码如下:
@api_view(['POST']) def add_to_cart(request): try: session_key = request.session.session_key if not session_key: request.session.create() session_key = request.session.session_key product_id = request.data.get('product') quantity = request.data.get('quantity') size_id = request.data.get('size') if not all([product_id, quantity, size_id]): return Response({'error': 'Missing required fields'}, status=status.HTTP_400_BAD_REQUEST) cart_item = Cart.objects.create( product_id=product_id, quantity=quantity, size_id=size_id, session_key=session_key ) serializer = CartSerializer(cart_item) return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) @api_view(['GET']) def get_cart_items(request): session_key = request.session.session_key cart_items = Cart.objects.filter(session_key=session_key) serializer = CartSerializer(cart_items, many=True) return Response(serializer.data)
问题根源
Django的request.session.create()仅生成session_key,但如果没有触发session的保存操作并返回Set-Cookie响应头,客户端下次请求不会携带该session_id,导致每次请求都生成新的session。单纯创建session_key未修改session字典时,Django默认不会自动发送Set-Cookie头。
修复方案
方案1:修改session字典触发自动保存
在创建session后,修改session字典的任意值,触发Django自动保存并发送Set-Cookie头:
@api_view(['POST']) def add_to_cart(request): try: session_key = request.session.session_key if not session_key: request.session.create() # 修改session字典,触发保存逻辑 request.session['cart_initialized'] = True session_key = request.session.session_key # 剩余代码保持不变 product_id = request.data.get('product') quantity = request.data.get('quantity') size_id = request.data.get('size') if not all([product_id, quantity, size_id]): return Response({'error': 'Missing required fields'}, status=status.HTTP_400_BAD_REQUEST) cart_item = Cart.objects.create( product_id=product_id, quantity=quantity, size_id=size_id, session_key=session_key ) serializer = CartSerializer(cart_item) return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
方案2:强制调用session保存方法
创建session后直接调用request.session.save(),强制触发保存和Cookie响应:
if not session_key: request.session.create() request.session.save() session_key = request.session.session_key
额外检查项
- 确保前端请求时正确携带Cookie,跨域场景下需开启
withCredentials: true(如axios等请求工具) - 检查Django配置中的
SESSION_COOKIE_HTTPONLY、SESSION_COOKIE_SECURE等参数是否匹配部署环境,避免Cookie无法被客户端存储
内容的提问来源于stack exchange,提问作者kemps
相关产品推荐
相关产品推荐

