Beispiel #1
0
    def post(self, request):
        """
        添加购物车
        """
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data.get('sku_id')
        count = serializer.validated_data.get('count')
        selected = serializer.validated_data.get('selected')

        # 尝试对请求的用户进行验证
        try:
            user = request.user
        except Exception:
            # 验证失败,用户未登录
            user = None

        if user is not None and user.is_authenticated:
            # 用户已登录,在redis中保存
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()
            # 记录购物车商品数量
            pl.hincrby('cart_%s' % user.id, sku_id, count)
            # 记录购物车的勾选项
            if selected:
                pl.sadd('cart_select_%s' % user.id, sku_id)
            pl.execute()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            # 用户未登录,在cookie中保存
            # {
            #     1001: { "count": 10, "selected": true},
            #     ...
            # }
            # 使用pickle序列化购物车数据,pickle操作的是bytes类型
            cart = request.COOKIES.get('cart')
            if cart is not None:
                cart = myjson.loads(cart)
            else:
                cart = {}

            sku = cart.get(sku_id)
            if sku:
                cart_count = int(sku.get('count'))
            else:
                cart_count = 0

            cart[sku_id] = {'count': count + cart_count, 'selected': selected}

            cookie_cart = myjson.dumps(cart)
            response = Response(serializer.data,
                                status=status.HTTP_201_CREATED)

            # 设置购物车的cookie
            # 需要设置有效期, 否则是临时cookie
            response.set_cookie('cart',
                                cookie_cart,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Beispiel #2
0
    def put(self, request):
        """
        修改购物车数据
        """
        serializer = CartSerializer(data=request.data)
        serializer.is_valid()
        sku_id = serializer.validated_data.get('sku_id')
        count = serializer.validated_data.get('count')
        selected = serializer.validated_data.get('selected')

        # 尝试对请求的用户进行验证
        try:
            user = request.user
        except Exception:
            # 验证失败,用户未登录
            user = None

        if user is not None and user.is_authenticated:
            # 用户已登录,在redis中保存
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()
            pl.hset('cart_%s' % user.id, sku_id, count)
            if selected:
                pl.sadd('cart_selected_%s' % user.id, sku_id)
            else:
                pl.srem('cart_selected_%s' % user.id, sku_id)
            pl.execute()
            return Response(serializer.data)
        else:
            # 用户未登录,在cookie中保存
            # 使用pickle序列化购物车数据,pickle操作的是bytes类型
            cart = request.COOKIES.get('cart')
            if cart is not None:
                cart = myjson.loads(cart)
            else:
                cart = {}

            cart[sku_id] = {'count': count, 'selected': selected}
            cookie_cart = myjson.dumps(cart)

            response = Response(serializer.data)
            # 设置购物车的cookie
            # 需要设置有效期,否则是临时cookie
            response.set_cookie('cart',
                                cookie_cart,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Beispiel #3
0
def merge_cart_cookie_to_redis(request, user, response):
    """
    合并请求用户的购物车数据,将未登录保存在cookie里的保存到redis中
    遇到cookie与redis中出现相同的商品时以cookie数据为主,覆盖redis中的数据
    :param request: 用户的请求对象
    :param user: 当前登录的用户
    :param response: 响应对象,用于清楚购物车cookie
    :return:
    """
    # 获取cookie中的购物车
    cookie_cart = request.COOKIES.get('cart')
    if not cookie_cart:
        return response

    # 解析cookie购物车数据
    cookie_cart = myjson.loads(cookie_cart)
    # 用于保存向redis购物车商品数量hash添加数据的字典
    cart = {}
    # 记录redis勾选状态中应该增加的sku_id
    redis_cart_selected_add = []
    # 记录redis勾选状态中应该删除的sku_id
    redis_cart_selected_remove = []

    # 合并cookie购物车与redis购物车,保存到cart字典中
    for sku_id, count_select_dict in cookie_cart.items():
        # 处理商品数量
        cart[sku_id] = count_select_dict['count']
        if count_select_dict['selected']:
            redis_cart_selected_add.append(sku_id)
        else:
            redis_cart_selected_remove.append(sku_id)

    if cart:
        redis_conn = get_redis_connection('cart')
        pl = redis_conn.pipeline()
        pl.hmset('cart_%s' % user.id, cart)
        if redis_cart_selected_add:
            pl.sadd('cart_selected_%s' % user.id, *redis_cart_selected_add)
        if redis_cart_selected_remove:
            pl.srem('cart_selected_%s' % user.id, *redis_cart_selected_remove)
        pl.execute()

    response.delete_cookie('cart')
    return response
Beispiel #4
0
    def get(self, request):
        """
        获取购物车
        """
        try:
            user = request.user
        except Exception:
            user = None

        if user is not None and user.is_authenticated:
            # 用户已登录,从redis中读取
            redis_conn = get_redis_connection('cart')
            redis_cart = redis_conn.hgetall('cart_%s' % user.id)
            redis_cart_selected = redis_conn.smembers('cart_selected_%s' %
                                                      user.id)
            cart = {}
            for sku_id, count in redis_cart.items():
                cart[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in redis_cart_selected
                }
        else:
            # 用户未登录,从cookie中读取
            cart = request.COOKIES.get('cart')
            if cart is not None:
                cart = myjson.loads(cart)
            else:
                cart = {}

        # 遍历处理购物车数据
        skus = SKU.objects.filter(id__in=cart.keys())
        for sku in skus:
            sku.count = cart[sku.id]['count']
            sku.selected = cart[sku.id]['selected']

        serializer = CartSKUSerializer(skus, many=True)
        return Response(serializer.data)
Beispiel #5
0
    def put(self, request):
        serializer = CartSelectAllSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        selected = serializer.validated_data['selected']

        try:
            user = request.user
        except Exception:
            user = None

        if user is not None and user.is_authenticated:
            redis_conn = get_redis_connection('cart')
            cart = redis_conn.hgetall('cart_%s' % user.id)
            sku_id_list = cart.keys()
            if selected:
                # 全选
                redis_conn.sadd('cart_selected_%s' % user.id, *sku_id_list)
            else:
                # 取消全选
                redis_conn.srem('car_selected_%s' % user.id, *sku_id_list)
            return Response({'message': 'OK'})
        else:
            cart = request.COOKIES.get('cart')

            response = Response({'message': 'OK'})

            if cart is not None:
                cart = myjson.loads(cart)
                for sku_id in cart:
                    cart[sku_id]['selected'] = selected
                cookie_cart = myjson.dumps(cart)
                # 设置购物车的cookie
                response.set_cookie('cart',
                                    cookie_cart,
                                    max_age=constants.CART_COOKIE_EXPIRES)

            return response
Beispiel #6
0
    def delete(self, request):
        """
        删除购物车数据
        """
        serializer = CartDeleteSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data['sku_id']

        try:
            user = request.user
        except Exception:
            user = None

        if user is not None and user.is_authenticated:
            # 用户已登录,在redis中保存
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()
            pl.hdel('cart_%s' % user.id, sku_id)
            pl.srem('cart_select_%s' % user.id, sku_id)
            pl.execute()
            return Response(status=status.HTTP_204_NO_CONTENT)
        else:
            # 用户未登录,在cookie中保存
            response = Response(status=status.HTTP_204_NO_CONTENT)
            cart = request.COOKIES.get('cart')
            if cart is not None:
                cart = myjson.loads(cart)
                if sku_id in cart:
                    del cart[sku_id]
                    cookie_cart = myjson.dumps(cart)
                    # 设置购物车的cookie
                    # 需要设置有效期,否则是临时cookie
                    response.set_cookie('cart',
                                        cookie_cart,
                                        max_age=constants.CART_COOKIE_EXPIRES)
                return response