def get(self, request): """ 获取购物车数据: 1,购物车中的商品数据 存放在redis中 sku_id count 根据sku_id 查询出商品数据 返回应该返回一个列表(所有的商品数据) 2,所有商品的总价格和总数量 """ user_id = request.session.get('ID') # 准备两个变量 total_price = 0 # 总价格 total_count = 0 # 总数量 # 1. 购物车中的商品数据 # 链接到redis cnn = get_redis_connection("default") # 从redis中获取购物车信息 # 准备car_key car_key = get_car_key(user_id) # 取数据 cars = cnn.hgetall(car_key) # 获取的是一个字段,遍历字典 # print(cars) # 准备一个变量 , 列表类型数据 ,保存多个商品 goodsList = [] for sku_id, count in cars.items(): # print(sku_id,count) sku_id = int(sku_id) # 商品id count = int(count) # 购物车数量 # 获取商品的数据 goods_sku = GoodsSKU.objects.get(pk=sku_id) # 需要购物车中商品的数量, 我们可以在goods_sku对象上新添加一个属性 goods_sku.count = count # 将该商品保存到商品列表中 goodsList.append(goods_sku) # 处理总价格和总数量 total_price += goods_sku.price * count total_count += count # 2,所有商品的总价格和总数量 # 构造字段 渲染数据 context = { "goodsList": goodsList, "total_price": total_price, "total_count": total_count, } return render(request, "sp_car/shopcart.html", context)
def get(self, request): """ 获取购物车数据 购物车中的商品数据 所有商品的总数量和总价格 """ user_id = request.session.get('ID') # 准备两个变量 total_price = 0 # 总价格 total_count = 0 # 总数量 # 1. 购物车中的总价格和总数量 # 连接redis cnn = get_redis_connection("default") # 从redis中获取购物车信息 # 准备car_key car_key = get_car_key(user_id) # 取数据 cars = cnn.hgetall(car_key) # 字典 ,遍历字典 # print(cars) # 准备一个变量,列表保存多个商品 goodsList = [] for sku_id, count in cars.items(): # print(sku_id,count) sku_id = int(sku_id) # 商品id count = int(count) # 商品数量 # 获取商品数据 goods_sku = GoodsSKU.objects.get(pk=sku_id) # 需要购物车中商品的数量,在goods_sku对象上添加一个属性 goods_sku.count = count # 将该商品保存到列表中 goodsList.append(goods_sku) # 处理总价格和总数量 total_count += count total_price += goods_sku.price * count # 2.所有商品的总价格和总数量 # 构造列表,渲染数据 context = { "goodsList": goodsList, "total_price": total_price, "total_count": total_count, "footer": 3 } return render(request, "sp_car/shopcart.html", context)
def post(self, request): # 1. 判断用户是否登录 user_id = request.session.get("ID") if user_id is None: return JsonResponse({"error": 1, "msg": "没有登录,请登录!"}) # 2. 接收请求参数 sku_id = request.POST.get("sku_id") count = request.POST.get("count") # 判断参数合法性 # 1.都要是整数 try: sku_id = int(sku_id) count = int(count) except: return JsonResponse({"error": 2, "msg": "参数错误!"}) # 2.商品必须要存在 try: goods_sku = GoodsSKU.objects.get(pk=sku_id) except GoodsSKU.DoesNotExist: return JsonResponse({"error": 3, "msg": "商品不存在!"}) # 3.库存判断 if goods_sku.stock < count: return JsonResponse({"error": 4, "msg": "库存不足!"}) # 将购物车数据添加到redis中 # 链接redis cnn = get_redis_connection("default") # 操作redis # 准备key car_key = get_car_key(user_id) # 添加数据到购物车 cnn.hincrby(car_key, sku_id, count) # 获取购物车中的总的商品的数量 car_values = cnn.hvals(car_key) # 保存到redis中的数据是 二进制编码了, 需要解码才能使用 total = 0 for v in car_values: total += int(v) # print(car_values) return JsonResponse({"error": 0, "msg": "添加成功", "total": total})
def post(self, request): # 1. 判断用户是否登录 user_id = request.session.get("ID") if user_id is None: return JsonResponse({"error": 1, "msg": "没有登录,请登录!"}) # 2. 接收请求参数 sku_id = request.POST.get("sku_id") count = -1 # 判断参数合法性 # 1.都要是整数 try: sku_id = int(sku_id) except: return JsonResponse({"error": 2, "msg": "参数错误!"}) # 2.商品必须要存在 try: goods_sku = GoodsSKU.objects.get(pk=sku_id) except GoodsSKU.DoesNotExist: return JsonResponse({"error": 3, "msg": "商品不存在!"}) # 从购物车中减去商品数量 # 链接redis cnn = get_redis_connection("default") # 操作redis # 准备key car_key = get_car_key(user_id) # 从购物车的数量减 cnn.hincrby(car_key, sku_id, count) # 如果商品sku_id对应的数量为0,就从购物车中删除该商品sku_id count = cnn.hget(car_key, sku_id) if int(count) < 1: cnn.hdel(car_key, sku_id) # 获取购物车中的总的商品的数量 car_values = cnn.hvals(car_key) # 保存到redis中的数据是 二进制编码了, 需要解码才能使用 total = 0 for v in car_values: total += int(v) return JsonResponse({"error": 0, "msg": "减少成功", "total": total})
def post(self, request): # 保存订单数据 """ 1. 必须登录 2. 接收请求参数(sku_ids 商品id addr_id 收货地址id transport 运输方式 描述 description) 判断参数合法性 3. 将数据保存到订单表 订单基本信息表(先创建) 订单商品表(多,后创建) 4. 清空对应商品在购物车(redis)中的数据 """ # 1. 验证是否登录 user_id = request.session.get("ID") if not user_id: return JsonResponse({"status": 1, "errmsg": "没有登录!"}) user = Users.objects.get(pk=user_id) # 2. 接收请求参数,判断参数的合法性 addr_id = request.POST.get('addr_id') sku_ids = request.POST.getlist("sku_ids") transport = request.POST.get("transport") description = request.POST.get("description") # 合法性判断 if not all([addr_id, sku_ids, transport]): return JsonResponse({"status": 2, "errmsg": "请求参数错误!"}) # 判断收货地址是否存在 try: address = UserAddress.objects.get(user_id=user_id, is_delete=False, pk=addr_id ) except UserAddress.DoesNotExist: return JsonResponse({"status": 3, "errmsg": "收货地址不存在"}) # 判断运输方式是否存在 try: trans = Transport.objects.get(pk=transport, is_delete=False) except Transport.DoesNotExist: return JsonResponse({"status": 4, "errmsg": "请运输方式!"}) # 3. 将数据保存到订单中 # 保存订单基本信息 # 准备订单编号 order_sn = "{}{}{}".format(datetime.now().strftime("%Y%m%d%H%M%S"), random.randrange(1000, 9999), user_id) # 收货人的地址 address_info = "{} {} {} {}".format(address.hcity, address.hproper, address.harea, address.brief) # 设置事务的保存点 save_point = transaction.savepoint() # 创建订单 判断是否成功 try: orderinfo = OrderInfo.objects.create(order_sn=order_sn, user=user, receiver=address.username, receiver_phone=address.phone, address=address_info, order_status=0, transport=trans, transport_price=trans.money, description=description) except Exception as e: print(e) return JsonResponse({"status": 5, "errmsg": "创建订单失败!"}) # 保存订单商品信息 # 准备一个变量保存商品总金额 order_goods_money = 0 # 链接到redis cnn = get_redis_connection("default") # 准备car_key car_key = get_car_key(user_id) for sku_id in sku_ids: # 判断商品是否存在 try: # 每次都锁定该商品 goods_sku = GoodsSKU.objects.select_for_update().get(pk=sku_id) # goods_sku = GoodsSKU.objects.get(pk=sku_id) except GoodsSKU.DoesNotExist: # 回滚事务 transaction.savepoint_rollback(save_point) return JsonResponse({"status": 6, "errmsg": "商品不存在!"}) # 保存订单商品信息 # 获取购物车中商品的数量 try: count = cnn.hget(car_key, sku_id) count = int(count) except: # 回滚事务 transaction.savepoint_rollback(save_point) return JsonResponse({"status": 10, "errmsg": "购物车中商品数量不存在"}) # count = 9999 # 判断库存是否足够 if goods_sku.stock < count: # 回滚事务 transaction.savepoint_rollback(save_point) return JsonResponse({"status": 7, "errmsg": "商品库存不足!"}) # time.sleep(10) try: order_goods = OrderGoods.objects.create(order=orderinfo, goods_sku=goods_sku, price=goods_sku.price, count=count) except: # 回滚事务 transaction.savepoint_rollback(save_point) return JsonResponse({"status": 8, "errmsg": "创建订单商品失败!"}) # 对应商品的库存 减少 销量增加 goods_sku.stock -= count # GoodsSKU.objects.filter(pk=goods_sku.pk,stock=goods_sku.stock) goods_sku.sale_num += count goods_sku.save() # 商品总金额计算 order_goods_money += goods_sku.price * count try: # 完善订单基本信息 # 获取 订单总金额和商品总金额 order_money = order_goods_money + trans.money orderinfo.order_money = order_money orderinfo.order_goods_money = order_goods_money orderinfo.save() except: # 回滚事务 transaction.savepoint_rollback(save_point) return JsonResponse({"status": 9, "errmsg": "更新订单失败"}) # 清空购物车 只清空对应的商品 cnn.hdel(car_key, *sku_ids) # 整个订单创建成功, 提交事务 transaction.savepoint_commit(save_point) return JsonResponse({"status": 0, "errmsg": "下单成功", "order_sn": order_sn})
def get(self, request): # 显示 # 接收参数 user_id = request.session.get("ID") """ 1. 需要商品的sku_ids (多个) 2. 请求方式为GET方式 """ # 1. 收货地址的显示 """ 1. 如果用户没有收货地址,点击添加 2. 如果有收货地址,并且有默认地址,显示默认地址 如果没有默认地址,显示最新的一个地址 3. 点击进去选择其他收货地址 """ address = UserAddress.objects.filter(user_id=user_id, is_delete=False, isDefault=True).first() if not address: # 没有默认的地址 address = UserAddress.objects.filter(user_id=user_id, is_delete=False).order_by("-create_time").first() # 2. 确认商品的显示 # 链接到redis cnn = get_redis_connection("default") # 准备 car_key car_key = get_car_key(user_id) # 接收商品的id 如果传入的字段的值是一个列表, getlist 方法 sku_ids = request.GET.getlist('sku_ids') # 准备一个变量装所有的商品 goodsList = [] goods_total_price = 0 # 获取商品的信息及对应购物车中的数量 for sku_id in sku_ids: # 获取商品的信息 goods_sku = GoodsSKU.objects.get(pk=sku_id) # 获取购物车中的数量 try: count = cnn.hget(car_key, sku_id) count = int(count) except: # 如果购物车中没有获取到商品数量,就跳转到购物车首页 return redirect(reverse("sp_car:首页")) # 提交到goods_sku对象上 goods_sku.count = count # 将商品信息存储到goodsList中 goodsList.append(goods_sku) # 计算商品总价 goods_total_price += goods_sku.price * count # 3. 商品总价和运输方式的选择 # 运输方式的选择 transports = Transport.objects.filter(is_delete=False).order_by("money") # 合计总价格 商品总价格 + 运费 transport = transports.first() total_price = goods_total_price + transport.money context = { "address": address, "goodsList": goodsList, "goods_total_price": goods_total_price, "total_price": total_price, "transports": transports, } return render(request, 'sp_order/tureorder.html', context)