当前位置: 首页 > 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.lryc.cn/news/621832.html

相关文章:

  • 【科研绘图系列】R语言绘制多种饼图
  • 20day-人工智能-机器学习-线性回归
  • 超高车辆碰撞预警系统如何帮助提升城市立交隧道安全?
  • 【机器学习深度学习】生成式评测
  • 金融项目高可用分布式TCC-Transaction(开源框架)
  • 服装企业客户满意度调查:民安智库的市场调研赋能实践(北京市场调查)
  • 汽车行业 AI 视觉检测方案(二):守护车身密封质量
  • 指针类型:解引用与运算的关键
  • 电子电气架构 --- 探索软件定义汽车(SDV)的技术革新
  • 基于多模型的零售销售预测实战指南
  • Java 大视界 -- 基于 Java 的大数据可视化在城市交通拥堵治理与出行效率提升中的应用(398)
  • 【java】对word文件设置只读权限
  • 英文PDF翻译成中文怎么做?试试PDF翻译工具
  • Canal 技术解析与实践指南
  • ffmpeg 安装、配置与使用完全指南
  • 【python实用小脚本-187】Python一键批量改PDF文字:拖进来秒出新文件——再也不用Acrobat来回导
  • fastdds.ignore_local_endpoints 属性
  • PDF Replacer:高效便捷的PDF文档内容替换专家
  • 基于 Spring AI + Ollama + MCP Client 打造纯本地化大模型应用
  • JavaScript(JS)DOM(四)
  • 大模型微调分布式训练-大模型压缩训练(知识蒸馏)-大模型推理部署(分布式推理与量化部署)-大模型评估测试(OpenCompass)
  • MuMu模拟器Pro Mac 安卓手机平板模拟器(Mac中文)
  • 代码随想录Day51:图论(岛屿数量 深搜广搜、岛屿的最大面积)
  • 解决量化模型中的 NaN 问题:为何非量化层应选用 FP32?(41)
  • 波浪模型SWAN学习(1)——模型编译与波浪折射模拟(Test of the refraction formulation)
  • Docker安装——配置国内docker镜像源
  • flutter 跨平台编码库 protobuf 工具使用
  • RAGFlow入门
  • Trae2.0:AI 编程新时代的引领者
  • 反射和类加载机制