介绍
购物车模块是我第一次遇到的这样的情况,购物车其实是将商品与用户进行多对多连接的一个中间环节。人对购物车是一对多,购物车对商品也是一对多,这样就实现了商品与人的多对多。(第一次接触多对多的关系)。另外购物车实现了商品与人关系的暂时储存,提交订单后要清空购物车。
1. model类的建立
这里的一个cart对象,并不是现实生活中的 购物车 ,一个cart对象相当于一个购物车 中的一个商品格子,储存了一种商品和商品的所有者,及商品的数量。所有的cart组成一个用户的购物车。
#用户 与 商品的 联系 是多对多的
#购物车 充当中间 环节,与 用户 一对多,同时 与 商品一对多
class Cart(models.Model):
user = models.ForeignKey('df_user.User')
goods = models.ForeignKey('df_goods.GoodInfo')
count = models.IntegerField()
2. 视图函数
1.购物车显示页面
这个页面就是根据用户获取所有的cart对象,传入模板,然后提取出商品信息和数量并加载
@user_decorator.login
def cart(request):
uid = request.session.get('uid')
carts = Cart.objects.filter(user_id=uid)
context = {'title': '购物车',
'name': 1,
'carts': carts}
return render(request, 'df_cart/cart.html', context)
2.加入购物车的视图函数
在模板中加入购物车的视图函数是通过ajax异步发送的,这样的化需要返回json格式的数据。传入参数为商品id和数量
@user_decorator.login
def add(request,gid,gcount):
gid = int(gid)
gcount = int(gcount)
uid = request.session.get('uid')
carts = Cart.objects.filter(goods_id=gid,user_id=uid)
#先判断 该用户 购物车中 是否 存在 该商品
#如果纯在,则仅作数量上的 加法
if len(carts) >= 1:
cart = carts[0]
cart.count += gcount
else:
cart = Cart()
cart.user_id = uid
cart.goods_id =gid
cart.count =gcount
cart.save()
#判断请求方式 是否是ajax,若是则返回json格式的 商品数量即可
if request.is_ajax():
count = Cart.objects.filter(user_id=uid).count()
return JsonResponse({'count':count})
else:
return redirect('/cart')
3.接下来是编辑购物车信息的请求函数
同样编辑购物车中的商品,数量信息也是通过ajax来异步请求的
def edit(request,cid,gcount):#传入 cart id 和 count 改变Cart
try:
cart = Cart.objects.get(pk=int(cid))
cart.count = int(gcount)
cart.save()
except:
return JsonResponse({'count':gcount})
#如果错误就将原来的数量返回去
return JsonResponse({'count':0})
4.最后是删除一行 购物车中的商品的 请求函数
直接做物理删除
def delete(request,cid):
try:
cart=Cart.objects.get(pk=int(cid))
cart.delete()
data ={'ok':1}
except:
data={'ok':0}
return JsonResponse(data)
3. 模板和js
购物车是用到js最多的地方,商品数量的加减,加入购物车,顶部购物车显示商品类别数量,小计与总计,从页面上删除一行商品。
1.购物车显示页面的js
<script>
$(function () {
total();
{# 全选全消#}
$('#check_all').click(function () {
{# 获取当前全选框的状态#}
state=$(this).prop('checked');
{# 将其他的选矿 都设置成这个状态#}
$(':checkbox:not(#ckeck_all)').prop('checked',state)
});
//选择
$(':checkbox:not(#check_all)').click(function () {
if($(this).prop('checked')){
alert($(':checked').length)
if($(':checked').length+1==$(':checkbox').length
){ $('#ckeck_all').prop('checked',true)
}
}
else{
$('#check_all').prop('checked',false)
}
});
//数量加
//为所有的 add绑定点击事件
$('.add').click(function () {
txt=$(this).next();
//数值加1,同时取消 焦点
txt.val(parseFloat(txt.val())+1).blur()
});
$('.minus').click(function () {
txt=$(this).prev();
//数值加1,同时取消 焦点
txt.val(parseFloat(txt.val())-1).blur()
});
//在blur事件里ajax 提交
$('.num_show').blur(function () {
count=$(this).val();
if(count<=0){
alert('数量不能小于0');
return
}else {};
id = $(this).parents('.cart_list_td').attr('id');
$.get('/cart/edit_'+id+'_'+count,function (data) {
if(data.count==0){
//修改成功,计算总价
alert('ok')
total();
}
else {
//修改失败,改为原来 的值(回掉回来原来的值)
$(this).val(data.count)
}
})
})
})
function cart_del(cart_id) {
del = confirm('确定删除');
if(del){
$.get('/cart/delete/'+cart_id,function (data) {
if(data.ok==1){
//删掉哪一行 商品
$('ul').remove('#'+cart_id);
total();
}
})
}
}
function total(){
total1=0;
total_count=0;
$('.col07').each(
function () {
//获取数量
count=$(this).prev().find('input').val();
//获取单价
price = $(this).prev().prev().text();
//计算小计
total0=parseFloat(count)*parseFloat(price);
//显示小计
$(this).text(total0.toFixed(2));
//加到总计上
total1 += total0;
total_count++;
});
//显示总计
$('#total').text(total1.toFixed(2));
$('.total_count1').text(total_count);
}
function go_order() {
s = '';
$(':checked:not(#check_all)').each(function () {
id = $(this).parents('.cart_list_td').attr('id');
s = s +'cart_id='+id + '&'
})
//删掉最后一个&
s=s.substring(0,s.length-1);
alert(s);
location.href = '/order?'+s ;
}
</script>
2.详情页加入购物车的js
里面的动画效果看不懂,但是主要请求看懂就行了
<script type="text/javascript">
var $add_x = $('#add_cart').offset().top;
var $add_y = $('#add_cart').offset().left;
var $to_x = $('#show_count').offset().top;
var $to_y = $('#show_count').offset().left;
$(".add_jump").css({'left':$add_y+80,'top':$add_x+10,'display':'block'})
$('#add_cart').click(function() {
{# 先判断是否登录#}
{# alert('点击');#}
if ($('.login_btn fl').text().indexOf('登录') >= 0) {
alert('请登陆后购买');
location.href('/user/login')
return
};
{# alert('ok');#}
$(".add_jump").stop().animate({
'left': $to_y + 7,
'top': $to_x + 7
},
"fast", function () {
$(".add_jump").fadeOut('fast', function () {
count =$('.num_show').val();
$.get('/cart/add_{{ goods.id }}_'+count.toString(),function (data) {
$('#show_count').html(data.count);
})
});
});
})
</script>
购物车基本完成了,收获很大,下一个是订单模块。