当前位置: 首页 > news >正文

17.3 删除购物车商品

分析与设计

删除购物车中的商品,需要接收sku_id,以JSON来响应。

实现

在carts应用下视图类CartsView中增加delete方法,全部代码为

import base64
import json
import picklefrom django.conf import settings
from django.http import HttpResponseForbidden, JsonResponse, HttpRequest
from django.shortcuts import render
from django.views import View
from django_redis import get_redis_connectionfrom carts import constants
from goods.models import SKU
from xiaoyu_mall_new.utils.response_code import RETCODEclass CartsView(View):def delete(self, request):"""删除购物车商品"""# 接收并校验参数json_dict = json.loads(request.body.decode())sku_id = json_dict.get('sku_id')# 判断商品是否存在try:SKU.objects.get(id=sku_id)except SKU.DoesNotExist:return HttpResponseForbidden('商品不存在')user = request.userif user.is_authenticated:# 登录redis_conn = get_redis_connection('carts')pl = redis_conn.pipeline()pl.hdel('carts_%s' % user.id, sku_id)pl.srem('selected_%s' % user.id, sku_id)pl.execute()return JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})else:# 未登录carts_str = request.COOKIES.get('carts')if carts_str:cart_dict = pickle.loads(base64.b64decode(carts_str.encode()))else:cart_dict = {}# 响应对象response = JsonResponse({'code': RETCODE.OK, 'errmsg': '删除购物车成功'})if sku_id in cart_dict:del cart_dict[sku_id]cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)return responsedef put(self, request):# 接收参数json_dict = json.loads(request.body.decode())sku_id = json_dict.get('sku_id')count = json_dict.get('count')selected = json_dict.get('selected')# 校验参数if not all([sku_id, count]):return HttpResponseForbidden('缺少必须的参数')try:sku = SKU.objects.get(id=sku_id)except SKU.DoesNotExist:return HttpResponseForbidden('商品sku_id不存在')try:count = int(count)except Exception:return HttpResponseForbidden('参数count有误')if selected:if not isinstance(selected, bool):return HttpResponseForbidden('参数selected 有误')user = request.userif user.is_authenticated:# 登录状态redis_conn = get_redis_connection('carts')pl = redis_conn.pipeline()pl.hset('carts_%s' % user.id, sku_id)if selected:pl.sadd('selected_%s' % user.id, sku_id)else:pl.srem('selected_%s' % user.id, sku_id)pl.execute()# 创建响应cart_sku = {'id': sku_id,'count': count,'selected': selected,'name': sku.name,'price': sku.price,'amount': sku.price * count,'stock': sku.stock,'default_image_url': settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg',}return JsonResponse({'code': RETCODE.OK, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})else:# 未登录 状态cart_str = request.COOKIES.get('carts')if cart_str:cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))else:cart_dict = {}cart_dict[sku_id] = {'count': count,'selected': selected}cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()cart_sku = {'id': sku_id,'count': count,'selected': selected,'name': sku.name,'price': sku.price,'amount': sku.price * count,'stock': sku.stock,'default_image_url': settings.STATIC_URL + 'images/goods/' + sku.default_image.url + '.jpg',}response = JsonResponse({'code': RETCODE.OK, 'errmsg': '修改购物车成功', 'cart_sku': cart_sku})response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)return responsedef get(self, request):# 判断用户是否登录user = request.userif user.is_authenticated:# 创建连接到redis的对象redis_conn = get_redis_connection('carts')# 查询user_id、count与sku_id构成的购物车记录redis_cart = redis_conn.hgetall('carts_%s' % user.id)# 查询勾选的商品smembers 命令返回集合中的所有的成员redis_selected = redis_conn.smembers('selected_%s' % user.id)cart_dict = {}for sku_id, count in redis_cart.items():cart_dict[int(sku_id)] = {"count": int(count),"selected": sku_id in redis_selected}else:# 用户未登录,查询cookies购物车cart_str = request.COOKIES.get('carts')if cart_str:# 对 cart_str进行编码,获取字节类型的数据cart_str_bytes = cart_str.encode()# 对cart_str_bytes进行解码,获取明文数据cart_dict_bytes = base64.b64decode(cart_str_bytes)# 对cart_dict_bytes反序列化,转换成Python能识别的字典类型的数据cart_dict = pickle.loads(cart_dict_bytes)else:cart_dict = {}# 构造响应数据sku_ids = cart_dict.keys()# 一次性查询出所有的skusskus = SKU.objects.filter(id__in=sku_ids)cart_skus = []for sku in skus:cart_skus.append({'id': sku.id,'count': cart_dict.get(sku.id).get('count'),# 将True,转'True',方便json解析'selected': str(cart_dict.get(sku.id).get('selected')),'name': sku.name,'default_image_url': settings.STATIC_URL +'images/goods/' + sku.default_image.url + '.jpg','price': str(sku.price),'amount': str(sku.price * cart_dict.get(sku.id).get('count')),'stock': sku.stock})context = {'cart_skus': cart_skus}# 渲染购物车页面return render(request, 'cart.html', context)def post(self, request):# 将JSON格式的字符串反序列化为Python对象json_dict = json.loads(request.body.decode())# 接收参数sku_id = json_dict.get('sku_id')count = json_dict.get('count')selected = json_dict.get('selected', True)# 校验参数if not all([sku_id, count]):return HttpResponseForbidden('缺少必要参数')# 校验sku_id参数try:SKU.objects.get(id=sku_id)except SKU.DoesNotExist:return HttpResponseForbidden('参数sku_id错误')# 校验count参数try:count = int(count)except Exception:return HttpResponseForbidden('参数count错误')# 校验selected参数if selected:if not isinstance(selected, bool):return HttpResponseForbidden('参数selected错误')# 判断用户是否登录user = request.user# 已登录,数据格式为:# carts_user_id:{sku_id1:count1,sku_id2:count2,...}# selected_user_id:{sku_id1,sku_id2,...}if user.is_authenticated:redis_conn = get_redis_connection('carts')# 创建管道,用于执行多个命令pl = redis_conn.pipeline()# 以增量形式保存商品数据# - 'carts_%s' % user.id :生成以用户ID为后缀的购物车键名(如 carts_123 )# - sku_id :商品SKU的唯一标识,作为哈希表的字段名# - count :要增加的数量(可为正数或负数)pl.hincrby('carts_%s' % user.id, sku_id, count)# 保存商品的勾选状态if selected:# 若selected为True,将sku_id添加到selected集合中pl.sadd('selected_%s' % user.id, sku_id)# 执行管道命令pl.execute()return JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})else:  # 未登录,购物车数据存储在cookie中,数据结构如下# cart_dict = {#     'sku_id1': {'count': 5, 'selected': 'True'},#     'sku_id2': {'count': 3, 'selected': 'False'}# ...# }cart_str = request.COOKIES.get('carts')# 若购物车数据存在,将其反序列化为字典if cart_str:# 对cart_str进行编码,获取字节类型数据cart_str_bytes = cart_str.encode()# 对密文类型数据cart_str_bytes进行base64解码,获取明文数据cart_dict_bytes = base64.b64decode(cart_str_bytes)# 对明文类型数据cart_dict_bytes进行反序列化,获取字典类型数据cart_dict = pickle.loads(cart_dict_bytes)# 若没有数据,创建空字典else:cart_dict = {}# 若购物车数据中已存在该商品,累加数量if sku_id in cart_dict:origin_count = cart_dict[sku_id]['count']count += origin_countcart_dict[sku_id] = {'count': count, 'selected': selected}# 对字典类型数据cart_dict进行序列化,获取字节类型数据cart_dict_bytes = pickle.dumps(cart_dict)# 对字节类型数据cart_dict_bytes进行base64编码,获取密文类型数据cart_str_bytes = base64.b64encode(cart_dict_bytes)# 对密文类型数据cart_str_bytes进行解码,获取明文类型数据cookie_cart_str = cart_str_bytes.decode()response = JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})response.set_cookie('carts', cookie_cart_str)# 响应结果return response

测试:在购物车商品列表页,点击“删除”即可删除商品,总金额同步更新。

http://www.dtcms.com/a/332536.html

相关文章:

  • @Autowired @Resource IDE警告 和 依赖注入
  • 【解决笔记】MyBatis-Plus 中无 selectList 方法
  • 【详细操作指南】如何将 Moodle 与编辑器连接,以修改文档、检查和批改作业等
  • JavaScript 核心基础:类型检测、DOM 操作与事件处理
  • 8.15 机器学习(2)K最近邻算法
  • Chrome插件开发【Tabs】
  • 基于vue和nodejs的茶叶销售平台的设计与实现/基于express的茶叶商城系统
  • 从 LLM 到自主 Agent:OpenCSG 打造开源 AgenticOps 生态
  • 从CAD数据访问到3D协作,HOOPS SDK如何提升PLM解决方案竞争力?
  • PCA降维全解析:从原理到实战
  • p5.js 3D盒子的基础用法
  • [TG开发]照片机器人
  • 云手机选哪个比较好用?
  • 【Docker】关于hub.docker.com,无法打开,国内使用dockers.xuanyuan.me搜索容器镜像、查看容器镜像的使用文档
  • 腾讯云开发小程序工具箱使用心得
  • Docker Compose 入门教程
  • Linux————网络基础
  • LPDDR5训练过程
  • 一、Docker本地安装
  • Kafka分区
  • 实现FPS武器的瞄准放大效果(UGUI实现反向遮罩,全屏遮挡,局部镂空效果)
  • 10--C++模板参数与特化详解
  • 【用软件方法实现临界区互斥】
  • Java 正则表达式的使用方法
  • 力扣326:3的幂
  • NLP数据增强方法及实现-A
  • 【R语言】R 语言中 gsub 与正则表达式详解(含 POSIX 与 Perl 风格实例)
  • 深入解析Java代理模式:灵活控制对象访问的核心技术
  • 配置国内加速源后仍然无法拉取镜像
  • 第五天~提取Arxml中CAN波特率属性New_CanCluster--Standard