在Django框架下,用redis实现购物车功能

先介绍一下本文中需要用到的数据库模型类

GoodsSKU,这个主要用于保存商品,在这个模型类里有price属性、name属性等。

最终我们要实现的页面效果是:

购买商品页面:


购物车详情页面:



总的思路是,因为购物车属于频繁被操作的对象,所以我们与之存储在数据库里,不如存储在内存里。所以我们选择redis。另外,购物车要显示用户购买商品的条目数,这个属于局部刷新,不能用户每次添加购物车都刷新整个页面,所以要用到ajax。

在数据传输方面,需要我们反复在前端与后端调用的数据是商品id(有了id,商品的其他信息就都能从数据库里查到。),购买的数量。

第一步,先来设计redis的数据结构,因为每个用户都要有一条数据,所以我们选择hash。具体的内容是cart_用户id:{商品1id : 数量, 商品2id:数量}条目数可以用hlen来获取。

第二步,用ajax实现前端与后台的沟通。

前端:

$(funcition(){

$('购物车').click(

function(){

# 获取用户购买的数量

count = $(相关的标签).val()

# 获取商品Id

sku_id = $(this).attr(' sku_id ')

# 不要忘了django的csrf验证,在网页随便一个地方添加{% csrf_token %}

csrf = $('input[name="csrfmiddlewaretoken"]').val()

params = {'sku_id':sku_id, 'count':count, 'csrfmiddlewaretoken':csrf}

$.post('/cart/add', params, function (data) {

# 显示条目数

$('#show_count').html(data.cart_count);

}

}

)

})

第三步,后台接受数据,并返回cart_count,条目数。

sku_id = request.POST.get('sku_id')
count = request.POST.get('count')

count = int(count)

conn = get_redis_connection('default')
cart_key = 'cart_%d'%user.id
cart_count = conn.hget(cart_key, sku_id)

# 如果用户买过该商品,直接在之前的数量上添加,没有买过,那么建立相应的键值对。

if cart_count:
            # 商品数目累加
            count += int(cart_count)

conn.hset(cart_key, sku_id, count)


        # 获取用户购物车中商品的条目数
        cart_count = conn.hlen(cart_key)


        # 返回应答
        return JsonResponse({'cart_count':cart_count, 'message':'添加成功'})

第四步,实现购物车详情页面。其实就是把相应的数据传过去。

def get(self, request):
        '''显示'''
        # 获取user
        user = request.user

        # 获取redis中对应用户的购物车记录 cart_用户id: {'sku_id':商品数目}
        conn = get_redis_connection('default')
        cart_key = 'cart_%d'%user.id

        cart_dict = conn.hgetall(cart_key) # {'sku_id':商品数量}

        skus = []
        total_count = 0
        total_price = 0
        # 获取购物车中商品id对应的商品信息
        for sku_id, count in cart_dict.items():
            # 根据sku_id获取商品的信息
            sku = GoodsSKU.objects.get(id=sku_id)
            # 计算商品的小计
            amount = sku.price*int(count)
            # 动态给sku对象增加属性amount和count, 分别保存商品的小计和购物车中商品的数量
            sku.amount = amount
            sku.count = count
            # 添加sku
            skus.append(sku)
            # 累加计算商品的总件数和总价格
            total_count += int(count)
            total_price += amount


        # 组织模板上下文
        context = {'total_count':total_count,
                   'total_price':total_price,
                   'skus':skus}

        # 使用模板
        return render(request, 'cart.html', context)


做个总结:做购物车,关键就是要清楚前端需要哪些数据,后端需要哪些数据,如何定制数据库里的数据结构。想清楚了,剩下的就是熟能生巧。