Complete e-commerce project--(7) Shopping cart module (1)

Shopping cart storage solution

  • There are two cases

User login

  • Describe the need for a complete shopping cart record
    • User, product, quantity, check status
    • Store data : user_id, sku_id, count, selected
    • storage location:
      • Choose redis database
      • Data storage type
        • (1) Select the hash type and save the user, product, quantity and other information.
          Insert picture description here
          The stored data should be: carts_user_id: {sku_id1: count, sku_id3: count, sku_id5: count, …}

        • (2) Checked state : adopt set type storage

        • Only store the sku_id of the checked product in the set, for example, the 1st and 3rd commodities are checked

        • 形式: selected_user_id: [sku_id1, sku_id3 ...]

1111111111111111111111111111111111

  • Storage logic description
    • When the item to be added to the shopping cart already exists, the quantity of the item is cumulatively calculated
    • When the product to be added to the shopping cart does not exist, just add field and value to the hash

User is not logged in

Storing data

  • Same as above user_id, sku_id, count, selected

storage location

  • Because the user is not logged in, the server cannot get the user ID
  • We can cache the shopping cart data of users who are not logged in to the user’s browser cookie, and each user’s own browser’s cookie stores their own shopping cart data

Storage type

  • (1) The type of data stored in the cookie of the browser is a string
  • (2) JSON string can describe string data with complex structure, which can ensure that a shopping cart record does not need to be stored separately
  • Data structure display :
{
    
    
    "sku_id1":{
    
    
        "count":"1",
        "selected":"True"
    },
    "sku_id3":{
    
    
        "count":"3",
        "selected":"True"
    },
    "sku_id5":{
    
    
        "count":"3",
        "selected":"False"
    }
}

Storage logic description

  • When the product to be added to the shopping cart already exists, the number of the product is cumulatively calculated.
  • When the product to be added to the shopping cart does not exist, just add field and value to the JSON

Data security processing:

  • (1) The string plaintext data stored in the browser cookie
    • We need to encrypt the data
  • (2) Solution: pickle module and base64 module

Introduction to the pickle module

  • The pickle module is a standard module of Python, which provides serialization operations on Python data, can convert the data to bytes type, and the serialization speed is fast .
  • Instructions:
    • pickle.dumps() serializes Python data into bytes type data
    • pickle.loads() deserialize bytes type data into python data.

Introduction to base64 module

  • Attention ! ! ! : The data serialized and converted by the pickle module is of type bytes , and the browser cookie cannot be stored
  • Introduction:
    • The base64 module is a standard module of Python, which can encode bytes type data and get bytes type ciphertext data
    • use:
      • base64.b64encode() Base64-encode the bytes type data and return the encoded bytes type data
      • base64.b64deocde() decodes the bytes type data encoded by base64 and returns the decoded bytes type data.

The following is the specific code implementation

Add shopping cart

redis

Insert picture description here

redis_conn = get_redis_connection('carts')
            pl = redis_conn.pipeline()
            # 新增购物车数据
            pl.hincrby('carts_%s' % user.id, sku_id, count)
            # 新增选中的状态
            if selected:
                pl.sadd('selected_%s' % user.id, sku_id)
            # 执行管道
            pl.execute()

cookie中

# 用户未登录,操作cookie购物车
            cart_str = request.COOKIES.get('carts')
            # 如果用户操作过cookie购物车
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:  # 用户从没有操作过cookie购物车
                cart_dict = {
    
    }

            # 判断要加入购物车的商品是否已经在购物车中,如有相同商品,累加求和,反之,直接赋值
            if sku_id in cart_dict:
                # 累加求和
                origin_count = cart_dict[sku_id]['count']
                count += origin_count
            cart_dict[sku_id] = {
    
    
                'count': count,
                'selected': selected
            }
            # 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
            cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()

            # 创建响应对象
            response = http.JsonResponse({
    
    'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
            # 响应结果并将购物车数据写入到cookie
            response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)

Delete shopping cart

redis

 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()

Delete cookie shopping cart

cart_str = request.COOKIES.get('carts')
            if cart_str:
                # 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
                cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
            else:
                cart_dict = {
    
    }

            # 创建响应对象
            response = http.JsonResponse({
    
    'code': RETCODE.OK, 'errmsg': '删除购物车成功'})
            if sku_id in cart_dict:
                del cart_dict[sku_id]
                # 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
                cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
                # 响应结果并将购物车数据写入到cookie
                response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)
            return response

The rest of the modifications and the display shopping cart are similar, so I won’t talk about it here.

Select all shopping cart

In redis:

# 用户已登录,操作redis购物车
            redis_conn = get_redis_connection('carts')
            cart = redis_conn.hgetall('carts_%s' % user.id)
            sku_id_list = cart.keys()
            if selected:
                # 全选
                redis_conn.sadd('selected_%s' % user.id, *sku_id_list)
            else:
                # 取消全选
                redis_conn.srem('selected_%s' % user.id, *sku_id_list)
            return http.JsonResponse({
    
    'code': RETCODE.OK, 'errmsg': '全选购物车成功'})

cookie中

# 用户已登录,操作cookie购物车
            cart = request.COOKIES.get('carts')
            response = http.JsonResponse({
    
    'code': RETCODE.OK, 'errmsg': '全选购物车成功'})
            if cart is not None:
                cart = pickle.loads(base64.b64decode(cart.encode()))
                for sku_id in cart:
                    cart[sku_id]['selected'] = selected
                cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
                response.set_cookie('carts', cookie_cart, max_age=constants.CARTS_COOKIE_EXPIRES)

Merge shopping cart

# 获取cookie中的购物车数据
    cookie_cart_str = request.COOKIES.get('carts')
    # cookie中没有数据就响应结果
    if not cookie_cart_str:
        return response
    cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart_str.encode()))

    new_cart_dict = {
    
    }
    new_cart_selected_add = []
    new_cart_selected_remove = []
    # 同步cookie中购物车数据
    for sku_id, cookie_dict in cookie_cart_dict.items():
        new_cart_dict[sku_id] = cookie_dict['count']

        if cookie_dict['selected']:
            new_cart_selected_add.append(sku_id)
        else:
            new_cart_selected_remove.append(sku_id)

    # 将new_cart_dict写入到Redis数据库
    redis_conn = get_redis_connection('carts')
    pl = redis_conn.pipeline()
    pl.hmset('carts_%s' % user.id, new_cart_dict)
    # 将勾选状态同步到Redis数据库
    if new_cart_selected_add:
        pl.sadd('selected_%s' % user.id, *new_cart_selected_add)
    if new_cart_selected_remove:
        pl.srem('selected_%s' % user.id, *new_cart_selected_remove)
    pl.execute()

    # 清除cookie
    response.delete_cookie('carts')

That's it. It's all about adding, deleting, modifying, and checking, operating cookies and redis. It's actually very cumbersome, but it's not difficult. You can understand the logic implementation carefully.

Guess you like

Origin blog.csdn.net/pythonstrat/article/details/108183169