python3 之 天天生鲜 购物车操作 更新与删除
是这鸟样的 当点击 + - 数量时 更新 ; 删除就是删除:
html
<li class="col06"> <div class="num_add"> <!-- class带fl 就可以通过 $('. ') 调用--> <a href="javascript:;" class="add fl">+</a> <!-- 没有定义name='count'或定义为其他名字不与detail相同 是为了区分订单页面来自 cart还是detail --> <input type="text" class="num_show fl" sku_id="{{ sku.id }}" value="{{sku.count}}"> <a href="javascript:;" class="minus fl">-</a> </div> </li> <li class="col07"><span>{{sku.amount}}</span>元</li> <li class="col08"><a href="javascript:;" class="del_btn">删除</a></li>
script
更新过数量 交给
updateRemoteCartInfo 函数处理
// 增加 $(".add").click(function(){ // 获取操作的商品id var sku_id = $(this).next().attr("sku_id"); // 获取加操作前的的数量 var sku_num = $(this).next().val(); // 进行数量加1 sku_num = parseInt(sku_num); sku_num += 1; // 显示商品数目的dom var num_dom = $(this).next(); // 更新购物车数量 updateRemoteCartInfo(sku_id, sku_num, num_dom); }); // 减少 $(".minus").click(function(){ // 获取操作的商品id var sku_id = $(this).prev().attr("sku_id"); // 获取加操作前的的数量 var sku_num = $(this).prev().val(); // 进行数量加1 sku_num = parseInt(sku_num); sku_num -= 1; if (sku_num < 1) sku_num = 1; // 更新页面显示数量 var num_dom = $(this).prev(); // 更新购物车数量 updateRemoteCartInfo(sku_id, sku_num, num_dom); }); var pre_sku_count = 0; $('.num_show').focus(function () { // 记录用户手动输入之前商品数目 pre_sku_count = $(this).val(); }); // 手动输入 $(".num_show").blur(function(){ var sku_id = $(this).attr("sku_id"); var sku_num = $(this).val(); // 如果输入的数据不合理,则将输入值设置为在手动输入前记录的商品数目 if (isNaN(sku_num) || sku_num.trim().length<=0 || parseInt(sku_num)<=0) { $(this).val(pre_sku_count); return; } sku_num = parseInt(sku_num); var num_dom = $(this); updateRemoteCartInfo(sku_id, sku_num, num_dom); });
// 更新后端购物车信息 function updateRemoteCartInfo(sku_id, sku_count, num_dom) { // 发送给后端的数据 var req = { sku_id: sku_id, count: sku_count, csrfmiddlewaretoken: "{{ csrf_token }}" }; $.post("/cart/update", req, function(data){ if (0 == data.code) { // 更新商品数量 $(num_dom).val(sku_count); // 更新商品金额信息 var sku_price = $(".cart_list_td[sku_id="+sku_id+"]").children('li.col05').children().text(); var sku_amount = parseFloat(sku_price) * sku_count; $(".cart_list_td[sku_id="+sku_id+"]").children('li.col07').children().text(sku_amount.toFixed(2)); // 更新顶部商品总数 freshTotalGoodsCount(); // 更新底部合计信息 freshOrderCommitInfo(); } else { alert(data.message); } }); }
#实现对数据库 及 cookie 商品的更新
class UpdateCartView(View): def post(self,request): #获取商品 id和count sku_id = request.POST.get('sku_id') count = request.POST.get('count') #验证数据完整性 if not all([sku_id, count]): return JsonResponse({'code': 1, 'message': '参数不完整'}) #验证 sku_id 在没有黑客攻击的情况下其实不会拿到None id try: sku = GoodsSKU.objects.get(id=sku_id) except GoodsSKU.DoesNotExist: return JsonResponse({'code': 2, 'message': '商品不存在'}) #保证 count 为整数 不能随意输入:字母、符号等无效 try: count = int(count) except Exception: return JsonResponse({'code': 3, 'message': '数量有误'}) #判断 库存 数量是否充足 if count > sku.stock: return JsonResponse({'code': 4, 'message': '库存不足'}) #判断用户是否登陆 if request.user.is_authenticated(): #获取用户id user_id = request.user.id #创建 redis 客户端 读取cart redis_conn = get_redis_connection('default') # 从数据库获取cart_%s 并判断 商品是否存在 if redis_conn.hget('cart_%s' % user_id,sku_id): #存在更新sku_id 数量 redis_conn.hset('cart_%s'%user_id,sku_id,count) return JsonResponse({'code': 0, 'message': '添加购物车成功'}) else:#不存在 基本不可能 可能黑客可以能造假id return JsonResponse({'code': 10, 'message': '购物车无该数据'}) else: # 判断cookie 中是否有 cart信息 为了更加安全加上判断 if request.COOKIES.get('cart'): # 如果 cookie中存在 cart 就加载出来 cart_dict = json.loads(request.COOKIES['cart']) if cart_dict[sku_id]: #如果存在 更新数量 cart_dict[sku_id] = count # 把新数据转换为json 进行序列化转储 dump:有 转储 的意思 new_cart = json.dumps(cart_dict) response = JsonResponse({'code': 0, 'message': '添加购物车成功'}) #设置 cookie 存入 response.set_cookie('cart',new_cart) return response
删除
// 删除 $(".del_btn").click(function(){ var sku_id = $(this).parents("ul").attr("sku_id"); var req = { sku_id: sku_id, csrfmiddlewaretoken: "{{ csrf_token }}" }; $.post('/cart/delete', req, function(data){ // window.reload() location.href="/cart/info/"; // 删除后,刷新页面 }); });
class DelCartView(View): def post(self,request): #获得商品 id sku_id = request.POST.get('sku_id') #验证商品是否存在 缓存等因素商品不存在 try: sku = GoodsSKU.objects.get(id=sku_id) except GoodsSKU.DoesNotExist: return JsonResponse({'code': 1, 'message': '商品不存在'}) # 判断用户是否登陆 if request.user.is_authenticated(): # 获取用户id user_id = request.user.id # 创建 redis 客户端 读取cart redis_conn = get_redis_connection('default') #验证商品 if redis_conn.hget('cart_%s'%user_id,sku_id): #删除 redis_conn.hdel('cart_%s'%user_id,sku_id) else: return JsonResponse({'code': 2, 'message': '商品不存在'}) return JsonResponse({'code': 0, 'message': '删除购物车成功'}) else: # 判断cookie 中是否有 cart信息 为了更加安全加上判断 if request.COOKIES.get('cart'): # 如果 cookie中存在 cart 就加载出来 cart_dict = json.loads(request.COOKIES['cart']) #验证 if cart_dict[sku_id]: #删除 del cart_dict[sku_id] #删除后的字典 在此序列 转储 new_cart = json.dumps(cart_dict) else: return JsonResponse({'code': 2, 'message': '商品不存在'}) response = JsonResponse({'code': 0, 'message': '删除购物车成功'}) #设置 cookie 存入 response.set_cookie('cart',new_cart) return response
更新 购物车总数 价格 全选与不全选
function freshOrderCommitInfo() { var total_amount = 0; //总金额 var total_count = 0; // 总数量 $('.cart_list_td').find(':checked').parents('ul').each(function () { var sku_amount = $(this).children('li.col07').text(); // 商品的金额 var sku_count = $(this).find('.num_show').val(); // 商品的数量 total_count += parseInt(sku_count); total_amount += parseFloat(sku_amount); }); // 设置商品的总数和总价 $("#total_amount").text(total_amount.toFixed(2)); $("#total_count").text(total_count); } // 更新页面顶端全部商品数量 function freshTotalGoodsCount() { var total_count = 0; $('.cart_list_td').find(':checkbox').parents('ul').each(function () { var sku_count = $(this).find('.num_show').val(); total_count += parseInt(sku_count); }); $(".total_count>em").text(total_count);
// 我的购物车后面的总数
$('#show_count').text(total_count);
}
// 商品对应checkbox发生改变时,全选checkbox发生改变 $('.cart_list_td').find(':checkbox').change(function () { // 获取商品所有checkbox的数目 var all_len = $('.cart_list_td').find(':checkbox').length; // 获取选中商品的checkbox的数目 var checked_len = $('.cart_list_td').find(':checked').length; if (checked_len < all_len){ // 有商品没有被选中 $('.settlements').find(':checkbox').prop('checked', false) } else{ // 所有商品都被选中 $('.settlements').find(':checkbox').prop('checked', true) } freshOrderCommitInfo(); }); // 全选和全不选 $('.settlements').find(':checkbox').change(function () { // 1.获取当前checkbox的选中状态 var is_checked = $(this).prop('checked'); // 2.遍历并设置商品ul中checkbox的选中状态 $('.cart_list_td').find(':checkbox').each(function () { // 设置每一个goods ul中checkbox的值 $(this).prop('checked', is_checked) }); freshOrderCommitInfo(); });
查看数据库 hash
hkeys 查看多有key(id)
hgetall 查看多有key和value(id、count)