如何在Django的views.py中遍历Session购物车数据并计算总价
购物车Session遍历异常与金额计算问题
我已将以下购物车数据存入Django Session,期望遍历数据并计算单个商品金额(数量×单价)及总金额:
dict_items([ ('1', {'name': 'Talon Lott', 'image': '/media/images/products/1.png', 'reg_price': '958.0', 'dis_price': '844.0', 'qty': 1}), ('2', {'name': 'Lionel Owens', 'image': '/media/images/products/2.png', 'reg_price': '684.0', 'dis_price': '221.0', 'qty': '1'}), ('3', {'name': 'Brenna Chan', 'image': '/media/images/products/3.png', 'reg_price': '728.0', 'dis_price': '177.0', 'qty': 1}), ('4', {'name': 'Amos Osborne', 'image': '/media/images/products/4.png', 'reg_price': '453.0', 'dis_price': '547.0', 'qty': '1'}) ])
但在views.py文件中遍历时仅能获取ID为1的商品:
{'name': 'Talon Lott', 'image': '/media/images/products/1.png', 'reg_price': '958.0', 'dis_price': '844.0', 'qty': 1}
以下是我的views.py代码(使用jQuery Ajax实现添加商品到购物车功能),请求解决遍历Session数据异常及金额计算问题:
# Add To Cart def add_to_cart(request): card_product = {} card_product[str(request.GET['id'])] ={ 'name': request.GET['name'], 'image': request.GET['image'], 'reg_price': request.GET['reg_price'], 'dis_price': request.GET['dis_price'], 'qty': request.GET['qty'] } # print(card_product) # print(id, name, image, reg_price, dis_price, qty) if 'cartdata' in request.session: if str(request.GET['id']) in request.session['cartdata']: card_data = request.session['cartdata'] card_data[str(request.GET['id'])]['qty'] = int(card_product[str(request.GET['id'])]['qty']) card_data.update(card_data) request.session['cartdata'] = card_data else: card_data = request.session['cartdata'] card_data.update(card_product) request.session['cartdata']= card_data else: request.session['cartdata'] = card_product return JsonResponse({ 'data':request.session['cartdata'], 'totalitems':len(request.session['cartdata']) }) # Cart Page View class CartListView(IndexView): template_name = 'cart/cart.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) total_amounts = 0 saving = 0 if 'cartdata' in self.request.session: for pro_id, item in self.request.session['cartdata'].items(): total_amounts += int(item['qty']) * float(item['dis_price']) saving += float(item['reg_price']) - float(item['dis_price']) print(item) context={ 'total_amounts': total_amounts, 'saving': saving, 'cart_data': self.request.session['cartdata'], 'totalitems': len(self.request.session['cartdata']) } return context else: context={ 'total_amounts': total_amounts, 'cart_data':0, 'totalitems': 0 } return context
问题修复方案
1. 解决遍历仅获取第一个商品的问题
CartListView的get_context_data方法中,return context写在了for循环内部,导致循环第一次迭代就直接返回上下文,后续商品无法遍历。将返回语句移到循环外部即可:
class CartListView(IndexView): template_name = 'cart/cart.html' def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) total_amounts = 0 saving = 0 if 'cartdata' in self.request.session: cart_data = self.request.session['cartdata'] for pro_id, item in cart_data.items(): qty = int(item['qty']) dis_price = float(item['dis_price']) reg_price = float(item['reg_price']) # 累加单个商品金额到总金额 total_amounts += qty * dis_price # 累加单个商品的总节省金额 saving += qty * (reg_price - dis_price) print(item) # 循环结束后统一组装上下文 context.update({ 'total_amounts': total_amounts, 'saving': saving, 'cart_data': cart_data, 'totalitems': len(cart_data) }) else: context.update({ 'total_amounts': total_amounts, 'cart_data': {}, # 用空字典替代0,避免模板处理异常 'totalitems': 0 }) return context
2. 修复add_to_cart中的冗余代码与类型问题
- 删除冗余的
card_data.update(card_data)操作 - 统一将qty存储为整数,避免后续计算出现类型错误:
def add_to_cart(request): product_id = str(request.GET['id']) card_product = { product_id: { 'name': request.GET['name'], 'image': request.GET['image'], 'reg_price': request.GET['reg_price'], 'dis_price': request.GET['dis_price'], 'qty': int(request.GET['qty']) # 直接转整数存储 } } if 'cartdata' in request.session: cart_data = request.session['cartdata'] if product_id in cart_data: # 更新已有商品数量 cart_data[product_id]['qty'] = card_product[product_id]['qty'] else: # 添加新商品到购物车 cart_data.update(card_product) request.session['cartdata'] = cart_data else: request.session['cartdata'] = card_product return JsonResponse({ 'data': request.session['cartdata'], 'totalitems': len(request.session['cartdata']) })
3. 修正总节省金额计算逻辑
原代码仅计算单个商品的差价,未乘以数量,修正后计算所有商品的总节省金额,确保数据准确。
内容的提问来源于stack exchange,提问作者Humayun Ahmed
相关产品推荐
相关产品推荐

