Exemple #1
0
    def test_add_item_to_a_cart(self):
        user = get_user_model().objects.get(id=1)
        product = Product.objects.get(id=1)
        product_2 = Product.objects.get(id=2)

        response = self.client.post(f'/api/v1/carts/items/{product.slug}/S/')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        response = self.client.post(f'/api/v1/carts/items/invalidslug/S/', **self.account_jwt(1))
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

        response = self.client.post(f'/api/v1/carts/items/{product.slug}/XXX/', **self.account_jwt(1))
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        response = self.client.post(f'/api/v1/carts/items/{product.slug}/S/', **self.account_jwt(1))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, CartSerializer(Cart.objects.get(user=user, checked_out=False)).data)

        response = self.client.post(f'/api/v1/carts/items/{product.slug}/S/', **self.account_jwt(1))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, CartSerializer(Cart.objects.get(user=user, checked_out=False)).data)

        response = self.client.post(f'/api/v1/carts/items/{product_2.slug}/M/', **self.account_jwt(1))
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data, CartSerializer(Cart.objects.get(user=user, checked_out=False)).data)
Exemple #2
0
    def post(self, request):
        """添加购物车"""
        # 接收参数(sku_id,count,selected)
        # 校验参数(序列化器)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']
        # cookie  string  {cart : {sku_id1:[ count, seleted ],sku_id2:[ count, seleted ] } }
        #
        # redis   string  {cart_user_id : {sku_id1:[ count, seleted ],sku_id2:[ count, seleted ] } }
        sku_id = str(sku_id)
        # cart_dict = self.read_cart(request)
        cart_dict = request.cart
        cart_dict[sku_id] = cart_dict.get(sku_id, None)
        if cart_dict[sku_id]:
            cart_dict[sku_id][0] += count
        else:
            cart_dict[sku_id] = [0, ""]
            cart_dict[sku_id][0] = count
        cart_dict[sku_id][1] = selected

        # response = Response(serializer.data, status=status.HTTP_201_CREATED)
        # self.write_cart(request, cart_dict, response)
        # return response
        return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemple #3
0
    def post(self, request):
        # 获取参数,并效验

        serializer = CartSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        flag = save_cart(request.user, serializer.validated_data)

        if flag:
            return Response(serializer.data, status=status.HTTP_201_CREATED)
Exemple #4
0
    def post(self, request, slug, size):
        """
        Add To Cart

        Appending new product to user's active cart,
        will create a new cart if no active cart exists.
        Will increase the quantity if the product with that size
        already exists on the user's cart.
        
        Allowed size parameters value are: 'S', 'M', 'L' either upper or lowercase
        """

        product = get_object_or_404(Product, slug=slug)
        if size.upper() not in ['S', 'M', 'L']:
            return Response(
                {
                    'details':
                    'Size parameter only accept S, M, or L either uppercase or lowercase'
                },
                status=status.HTTP_400_BAD_REQUEST)

        product_cart, product_created = ProductCart.objects.get_or_create(
            user=request.user,
            product=product,
            size=size.upper(),
            defaults={'selected': True})

        if not product_created:
            product_cart.qty += 1
            product_cart.save()

        serializer = CartSerializer(
            Cart.objects.get(user=request.user, checked_out=False))
        return Response(serializer.data, status=status.HTTP_200_OK)
Exemple #5
0
    def put(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')

        sku_id = str(sku_id)
        # cart_dict = self.read_cart(request)
        cart_dict = request.cart
        cart_dict[sku_id] = [count, selected]
        # response = Response(serializer.data)
        # self.write_cart(request, cart_dict, response)
        # return response
        return Response(serializer.data)
Exemple #6
0
    def put(self, request):
        """
        修改购物车数据
        """
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        goods_id = serializer.data.get('goods_id')
        count = serializer.data.get('count')

        # 尝试对请求的用户进行验证
        user = request.user
        redis_conn = get_redis_connection('cart')
        redis_conn.hset('cart_%s' % user.id, goods_id, count)

        datas = {  # 返回购物车总条数
            'total_count': get_cart_count(request, redis_conn)
        }
        return Response(datas)
Exemple #7
0
    def post(self, request):
        """
        添加购物车
        """
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        goods_id = serializer.data.get('goods_id')
        count = serializer.data.get('count')

        # 尝试对请求的用户进行验证
        user = request.user
        # 用户已登录,在redis中保存
        redis_conn = get_redis_connection('cart')   # type: StrictRedis
        # 记录购物车商品数量
        redis_conn.hincrby('cart_%s' % user.id, goods_id, count)

        datas = {   # 返回购物车总条数
            'total_count': get_cart_count(request, redis_conn)
        }
        return Response(datas)
Exemple #8
0
 def create(self, request, *args, **kwargs):
     cart = self.get_cart()
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     serializer.save(cart=cart)
     cart_serializer = CartSerializer(cart)
     headers = self.get_success_headers(serializer.data)
     response = Response(cart_serializer.data,
                         status=status.HTTP_201_CREATED,
                         headers=headers)
     return self.append_cookie(response, cart)
Exemple #9
0
    def post(self, request):
        cart = self.get_cart(request)
        cart.checked_out = True

        for product in cart.products.all():
            product.checked_out = True
            product.save()

        cart.save()
        serialize = CartSerializer(cart)
        return Response(serialize.data)
Exemple #10
0
    def test_get_all_carts(self):
        user = get_user_model().objects.get(id=1)
        carts = CartSerializer(Cart.objects.filter(user=user), many=True)

        response = self.client.get('/api/v1/carts/')
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

        response = self.client.get('/api/v1/carts/', **self.account_jwt(1))
        if carts.data == []:
            self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)
        else:
            self.assertEqual(response.data, carts.data)
Exemple #11
0
class DetailedOrderSerializer(serializers.ModelSerializer):
    customer = CustomerSerializer()
    cart = CartSerializer()

    class Meta:
        model = Order
        fields = [
            'customer', 'order_id', 'cart', 'status', 'timestamp',
            'shipping_total', 'cart_total', 'tax_total', 'total',
            'total_in_paise', 'address', 'city', 'state'
        ]

        total_in_paise = IntegerField(source='total_in_paise')
Exemple #12
0
class ToggleCartItem(APIView):
    permission_classes = [IsActive]

    @swagger_auto_schema(
        responses={
            200: CartSerializer(),
            400: 'Invalid Size Parameter',
            404: 'Can\'t Find Product With That Slug'
        })
    def post(self, request, slug, size):
        """
        Toggle Item Selected Status From Cart

        Toggle mentioned product selected status from its active cart.
        If the product is unselected it will be selected and vice versa.
        
        Allowed size parameters value are: 'S', 'M', 'L' either upper or lowercase
        """
        user = request.user

        try:
            cart = Cart.objects.get(user=user, checked_out=False)
            if size.upper() not in ['S', 'M', 'L']: raise ValueError
            product_cart = ProductCart.objects.get(product__slug=slug,
                                                   size=size,
                                                   cart=cart)
        except (Cart.DoesNotExist, ProductCart.DoesNotExist) as e:
            if e == Cart.DoesNotExist:
                Cart.objects.create(user=user)
            return Response(
                {
                    'detail':
                    f'Trying to toggle selected status of non existing product from {user.username} cart'
                },
                status=status.HTTP_404_NOT_FOUND)
        except ValueError:
            return Response(
                {
                    'details':
                    'Size parameter only accept S, M, or L either uppercase or lowercase'
                },
                status=status.HTTP_400_BAD_REQUEST)

        product_cart.selected = not product_cart.selected
        product_cart.save()

        serializer = CartSerializer(
            Cart.objects.get(user=user, checked_out=False))
        return Response(serializer.data)
Exemple #13
0
    def delete(self, request, slug, size):
        """
        Remove From Cart

        Removing product from user's active cart,
        will create a new cart if no active cart exists.
        Will decrease the quantity if the product with that size
        have more than 1 quantity on the cart.
        
        Allowed size parameters value are: 'S', 'M', 'L' either upper or lowercase
        """

        user = request.user

        try:
            cart = Cart.objects.get(user=user, checked_out=False)
            if size.upper() not in ['S', 'M', 'L']: raise ValueError
            product_cart = ProductCart.objects.get(product__slug=slug,
                                                   size=size,
                                                   cart=cart)
        except (Cart.DoesNotExist, ProductCart.DoesNotExist) as e:
            if e == Cart.DoesNotExist:
                Cart.objects.create(user=user)
            return Response(
                {
                    'detail':
                    f'Trying to remove non existing product from {user.username} cart'
                },
                status=status.HTTP_404_NOT_FOUND)
        except ValueError:
            return Response(
                {
                    'details':
                    'Size parameter only accept S, M, or L either uppercase or lowercase'
                },
                status=status.HTTP_400_BAD_REQUEST)

        if product_cart.qty > 1:
            product_cart.qty -= 1
            product_cart.save()
        else:
            product_cart.delete()

        serializer = CartSerializer(
            Cart.objects.get(user=user, checked_out=False))
        return Response(serializer.data)
Exemple #14
0
    def post(self, request):
        payload = request.auth.payload

        user_id = payload["user_id"]
        user = User.objects.get(id=user_id)

        item_id = request.data["item"]
        item = Item.objects.get(id=item_id)
        quantity = request.data["quantity"]

        try:
            cart = Cart.objects.get(owner=user, item=item)
            cart.quantity += quantity
        except:
            cart = Cart(owner=user, item=item, quantity=quantity)

        cart.save()
        return Response(CartSerializer(instance=cart).data)
Exemple #15
0
    def get(self, request):
        user = request.user
        cart_qs = Cart.objects.filter(user__username=user)
        cart_condition = None
        if request.GET.get('checked') == 'true':
            cart_condition = True
        elif request.GET.get('checked') == 'false':
            cart_condition = False

        cart_qs = cart_qs.filter(checked_out=cart_condition
                                 ) if not cart_condition == None else cart_qs
        carts = [cart for cart in cart_qs]

        if not carts:
            # Return early with no content (204) if no queryset found
            return Response(status=status.HTTP_204_NO_CONTENT)

        serializer = CartSerializer(carts, many=True)
        return Response(serializer.data)
Exemple #16
0
class DetailedOrderSerializer(serializers.ModelSerializer):
    billing_profile = BillingProfileSerializer()
    cart = CartSerializer()

    class Meta:
        model = Order
        fields = [
            'billing_profile',
            'order_id',
            'cart',
            'status',
            'timestamp',
            'shipping_total',
            'cart_total',
            'tax_total',
            'total',
            'total_in_paise',
        ]

        total_in_paise = IntegerField(source='total_in_paise')
Exemple #17
0
class Carts(APIView):
    """
    Cart List

    Return a list of user's cart if request is authenticated
    else return 401 code.<br>
    You can set a GET parameter to filter its result.<br>

    GET parameter list:
    **checked**: If set to 'true' will return only checked out cart,
    else if you set it to 'false' will return only non checked out cart (active cart)
    """

    permission_classes = [IsActive]

    @swagger_auto_schema(
        responses={
            200: CartSerializer(),
            204: 'No Result Found',
            401: 'Invalid User\'s Credential'
        })
    def get(self, request):
        user = request.user
        cart_qs = Cart.objects.filter(user__username=user)
        cart_condition = None
        if request.GET.get('checked') == 'true':
            cart_condition = True
        elif request.GET.get('checked') == 'false':
            cart_condition = False

        cart_qs = cart_qs.filter(checked_out=cart_condition
                                 ) if not cart_condition == None else cart_qs
        carts = [cart for cart in cart_qs]

        if not carts:
            # Return early with no content (204) if no queryset found
            return Response(status=status.HTTP_204_NO_CONTENT)

        serializer = CartSerializer(carts, many=True)
        return Response(serializer.data)
Exemple #18
0
 def cart(self, request, pk=None):
     user = self.get_object()
     books = Cart.objects.all().filter(Q(user=user))
     serialized = CartSerializer(books, many=True)
     return Response(serialized.data)
Exemple #19
0
    def put(self, request):
        """
        用户的购物车记录更新:
        1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,商品库存是否足够)
        2. 获取user并处理
        3. 更新用户的购物车记录
            3.1 如果用户已登录,更新redis中对应购物车记录
            3.2 如果用户未登录,更新cookie中对应购物车记录
        4. 返回应答,购物车记录更新成功
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取参数
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count'] # 更新结果
        selected = serializer.validated_data['selected'] # 更新勾选状态

        # 2. 获取user并处理
        try:
            # 调用request.user会触发DRF的认证,在这里如果认证处理,可以自己进行处理
            user = request.user
        except Exception:
            user = None

        # 3. 更新用户的购物车记录
        if user is not None and user.is_authenticated:
            # 3.1 如果用户已登录,更新redis中对应购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')

            # 在redis中更新对应sku_id商品的购物车数量count  hash
            cart_key = 'cart_%s' % user.id

            pl = redis_conn.pipeline()

            # hset(key, field, value): 将redis中hash的属性field设置值为value
            pl.hset(cart_key, sku_id, count)

            # 在redis中更新sku_id商品的勾选状态 set
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                # 勾选
                # sadd(key, *members): 将set集合添加元素,不需要关注元素是否重复
                pl.sadd(cart_selected_key, sku_id)
            else:
                # 取消勾选
                # srem(key, *members): 从set集合移除元素,有则移除,无则忽略
                pl.srem(cart_selected_key, sku_id)

            pl.execute()

            # 返回应答
            return Response(serializer.data)
        else:
            response = Response(serializer.data)
            # 3.2 如果用户未登录,更新cookie中对应购物车记录
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart is None:
                return response

            # 解析cookie中的购物车数据
            cart_dict = pickle.loads(base64.b64decode(cookie_cart)) # {}
            if not cart_dict:
                return response

            # 更新用户购物车中sku_id商品的数量和勾选状态
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }

            # 4. 返回应答,购物车记录更新成功
            # 设置购物车cookie数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()  # str
            response.set_cookie('cart', cart_data, max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #20
0
    def post(self, request):
        """
        购物车记录添加:
        1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,商品库存是否足够)
        2. 保存用户的购物车记录
            2.1 如果用户已登录,在redis中保存用户的购物车记录
            2.2 如果用户未登录,在cookie中保存用户的购物车记录
        3. 返回应答,购物车记录添加成功
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取参数
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 获取user
        try:
            # 调用request.user会触发DRF的认证,在这里如果认证处理,可以自己进行处理
            user = request.user
        except Exception:
            user = None

        # 2. 保存用户的购物车记录
        if user is not None and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中保存用户的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')

            # 在redis中存储用户的添加的商品的sku_id和对应数量count hash
            cart_key = 'cart_%s' % user.id

            pl = redis_conn.pipeline()
            # 如果sku_id商品在用户的购物车记录已经添加过,数量count需要进行累加
            # 如果sku_id商品在用户的购物车记录没有添加过,直接设置新的属性和值
            # hincrby(key, field, amount): 给hash指定的field的值累加amount,如果field不存在,新建属性和值
            pl.hincrby(cart_key, sku_id, count)

            # 在redis中存储用户购物车记录勾选状态 set
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                # 勾选
                # sadd(key, *members): 将set集合添加元素,不需要关注元素是否重复
                pl.sadd(cart_selected_key, sku_id)

            pl.execute()

            # 返回应答
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            # 2.2 如果用户未登录,在cookie中保存用户的购物车记录
            # 获取cookie中购物车数据
            cookie_cart = request.COOKIES.get('cart') # None

            if cookie_cart:
                # 解析购物车数据
                # {
                #     '<sku_id>': {
                #         'count': '<count>',
                #         'selected': '<selected>'
                #     },
                #     ...
                # }
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}

            # 保存购物车记录
            if sku_id in cart_dict:
                # 数量进行累加
                count += cart_dict[sku_id]['count']

            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }

            # 3. 返回应答,购物车记录添加成功
            response = Response(serializer.data, status=status.HTTP_201_CREATED)

            # 设置购物车cookie数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode() # str
            response.set_cookie('cart', cart_data, max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #21
0
    def post(self, request):
        """
        购物车记录保存:
        1. 获取参数并进行校验(参数完整性,sku_id是否存在,商品库存是否足够)
        2. 保存用户的购物车记录
            2.1 如果用户已登录,在redis中存储用户的购物车记录
            2.2 如果用户未登录,在cookie中存储用户的购物车记录
        3. 返回应答,购物车记录添加成功
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取检验之后的数据
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 获取user
        try:
            # 只有使用request.user,就会触发DRF框架认证机制
            user = request.user
        except Exception:
            user = None

        # 2. 保存用户的购物车记录
        if user and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中存储用户的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')

            # hash: 存储登录用户购物车添加的商品id和对应数量count
            # 如果该商品已经添加过,购物车记录中商品的数量需要进行累加
            cart_key = 'cart_%s' % user.id
            redis_conn.hincrby(cart_key, sku_id, count)

            # set: 存储登录用户购物车中被勾选的商品的id
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                redis_conn.sadd(cart_selected_key, sku_id)

            return Response(serializer.validated_data,
                            status=status.HTTP_201_CREATED)
        else:
            # 2.2 如果用户未登录,在cookie中存储用户的购物车记录
            # 获取cookie中原有的购物车记录
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart:
                # 解析cookie中的购物车数据
                # {
                #     '<sku_id>': {
                #         'count': '<count>',
                #         'selected': '<selected>'
                #     },
                #     ...
                # }
                cart_dict = pickle.loads(base64.b64decode(
                    cookie_cart.encode()))
            else:
                cart_dict = {}

            # 保存购物车记录
            if sku_id in cart_dict:
                # 数据累加
                count += cart_dict[sku_id]['count']

            cart_dict[sku_id] = {'count': count, 'selected': selected}

            # 3. 返回应答,购物车记录添加成功
            response = Response(serializer.data,
                                status=status.HTTP_201_CREATED)
            # 设置cookie购物车数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart',
                                cart_data,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #22
0
    def put(self, request):
        """
        修改购物车记录:
        1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,count是否大于库存)
        2. 修改用户的购物车记录
            2.1 如果用户已登录,修改redis中对应的购物车记录
            2.2 如果用户未登录,修改cookie中对应的购物车记录
        3. 返回应答,购物车记录修改成功
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id对应的商品是否存在,count是否大于库存)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取校验之后的参数
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']  # 修改数量
        selected = serializer.validated_data['selected']  # 修改勾选状态

        try:
            # 触发DRF认证机制
            user = request.user
        except Exception:
            user = None

        # 2. 修改用户的购物车记录
        if user and user.is_authenticated:
            # 2.1 如果用户已登录,修改redis中对应的购物车记录
            # redis链接
            redis_conn = get_redis_connection('cart')

            # 修改hash中sku_id属性对应值
            cart_key = 'cart_%s' % user.id
            redis_conn.hset(cart_key, sku_id, count)

            # 修改勾选状态
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                # 将sku_id添加到set中
                redis_conn.sadd(cart_selected_key, sku_id)
            else:
                # 将sku_id从set中移除
                redis_conn.srem(cart_selected_key, sku_id)

            return Response(serializer.validated_data)
        else:
            # 2.2 如果用户未登录,修改cookie中对应的购物车记录
            response = Response(serializer.validated_data)

            # 获取cookie购物车记录
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart is None:
                # cookie购物车无数据,不需要修改
                return response

            # 解析cookie购物车数据
            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>'
            #     },
            #     ...
            # }
            cart_dict = pickle.loads(base64.b64decode(
                cookie_cart.encode()))  # {}

            if not cart_dict:
                # 字典为空,购物车无数据,不需要修改
                return response

            # 保存修改的数据
            cart_dict[sku_id] = {'count': count, 'selected': selected}

            # 3. 返回应答,购物车记录修改成功
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart',
                                cart_data,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #23
0
    def post(self, request):
        """
        购物车记录添加:
        1. 接收参数并进行参数校验(参数完整性,sku_id商品是否存在,count是否大于库存)
        2. 保存添加的购物车记录
            2.1 如果用户已登录,在redis中保存用户的购物车记录
            2.2 如果用户未登录,在cookie中保存用户的购物车记录
        3. 返回应答
        """
        # 1. 接收参数并进行参数校验(参数完整性,sku_id商品是否存在,count是否大于库)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取参数
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 获取user
        try:
            user = request.user
        except Exception as e:
            user = None

        # 2. 保存添加的购物车记录
        if user is not None and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中保存用户的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()

            # 在redis中存储用户添加的商品id和对应数量 hash
            cart_key = 'cart_%s' % user.id

            # 如果用户的购物车记录中已经添加过该商品,数量需要进行累加
            # 如果用户的购物车记录中没有添加过该商品,设置一个新的属性和值
            # hincrby(key, field, value): 给hash中field属性值累加一个value,如果field不存在,新建一个属性和值
            pl.hincrby(cart_key, sku_id, count)

            # 在redis中存储用户购物车记录勾选状态 set
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                # 勾选
                # sadd(key, *values): 向set中添加元素,不需要关注是否重复,set中元素唯一
                pl.sadd(cart_selected_key, sku_id)

            pl.execute()

            # 返回应答
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            # 2.2 如果用户未登录,在cookie中保存用户的购物车记录
            # 尝试从cookie中获取原始的购物车数据
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart:
                # 解析cookie中购物车数据
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}

            # 保存用户购物车添加数据
            if sku_id in cart_dict:
                # 数量进行累加
                count += cart_dict[sku_id]['count']

            cart_dict[sku_id] = {'count': count, 'selected': selected}

            # 设置购物车cookie数据
            response = Response(serializer.data,
                                status=status.HTTP_201_CREATED)
            # response.set_cookie(key, value, expires)
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart',
                                cart_data,
                                expires=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #24
0
    def post(self, request):
        """
        购物车记录添加:
        1. 接收参数并进行校验(sku_id对应的商品是否存在,商品库存是否足够)
        2. 保存用户的购物车记录数据
            2.1 如果用户已登录,在redis中保存用户的购物车记录
            2.2 如果用户未登录,在cookie中保存用户的购物车记录
        3. 返回应答,购物车记录添加成功
        """
        # 1. 接收参数并进行校验(sku_id对应的商品是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取校验之后的数据
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 获取user
        # request.user会触发DRF框架的认证过程,但是此处的代码是我们自己调用的,所有自己进行处理
        try:
            user = request.user
        except Exception as e:
            user = None

        # 2. 保存用户的购物车记录数据
        if user is not None and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中保存用户的购物车记录
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()

            # 在redis hash元素中存储用户添加的商品sku_id和对应数量count
            cart_key = 'cart_%s' % user.id

            # 如果用户的购物车记录中已经添加过该商品,商品的对应数量需要进行累加,否则直接添加新元素
            # hincrby(key, field, count): 给hash中指定属性field的值累加count,如果field不存在,新建属性和值
            pl.hincrby(cart_key, sku_id, count)

            # 在redis set元素中存储用户添加购物车记录时勾选商品sku_id
            cart_selected_key = 'cart_selected_%s' % user.id
            if selected:
                # 勾选
                # sadd(key, *members): 向set集合中添加元素,元素是唯一的
                pl.sadd(cart_selected_key, sku_id)

            pl.execute()

            # 返回应答
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            # 2.2 如果用户未登录,在cookie中保存用户的购物车记录
            # 获取原始的购物车数据
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart:
                # 解析cookie中的购物车数据
                # {
                #     '<sku_id>': {
                #         'count': '<count>',
                #         'selected': '<selected>'
                #     },
                #     ...
                # }
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}

            # 保存用户的购物车数据
            if sku_id in cart_dict:
                # 累加数量
                count += cart_dict[sku_id]['count']

            cart_dict[sku_id] = {'count': count, 'selected': selected}

            # 3. 返回应答,购物车记录添加成功
            response = Response(serializer.data,
                                status=status.HTTP_201_CREATED)
            # 设置cookie购物车数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart',
                                cart_data,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #25
0
    def post(self, request):
        """
        request.user:
            如果用户已登录,request.user就是登录用户对象
            如果用户未登录,request.user就是一个匿名用户类对象
        购物车记录添加:
        1. 获取参数并进行校验(参数完整,sku_id商品是否存在,商品库存是否足够)
        2. 保存用户的购物车记录
            2.1 如果用户已登录,在redis中保存用户的购物车记录
            2.2 如果用户未登录,在cookie中保存用户的购物车记录
        3. 返回应答,购物车记录添加成功
        """
        # 1. 获取参数并进行校验(参数完整,sku_id商品是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取校验之后的数据
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected'] # True: 勾选

        # 获取user
        try:
            # 调用request.user会触发DRF框架认证过程
            user = request.user
        except Exception:
            user = None

        # 2. 保存用户的购物车记录
        if user and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中保存用户的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')

            # hash: 在redis hash中存储用户购物车添加的商品id和数量count
            cart_key = 'cart_%s' % user.id

            # 如果购物车已经添加过该商品,数量需要进行累加,如果未添加,直接添加一个新元素
            redis_conn.hincrby(cart_key, sku_id, count)

            # set: 在redis set中存储用户购物车勾选的商品id
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                redis_conn.sadd(cart_selected_key, sku_id)

            return Response(serializer.validated_data, status=status.HTTP_201_CREATED)
        else:
            # 2.2 如果用户未登录,在cookie中保存用户的购物车记录
            # 获取原始cookie的购物车数据
            cookie_cart = request.COOKIES.get('cart') # None

            if cookie_cart:
                # 解析cookie中购物车数据
                # {
                #     '<sku_id>': {
                #         'count': '<count>',
                #         'selected': '<selected>'
                #     },
                #     ...
                # }
                cart_dict = pickle.loads(base64.b64decode(cookie_cart))
            else:
                cart_dict = {}

            # 如果购物车已经添加过该商品,数量需要进行累加
            if sku_id in cart_dict:
                count += cart_dict[sku_id]['count']

            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }

            # 3. 返回应答,购物车记录添加成功
            response = Response(serializer.validated_data, status=status.HTTP_201_CREATED)
            # 设置cookie中购物车数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart', cart_data, max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #26
0
    def put(self, request):
        """
        购物车记录修改:
        1. 获取参数并进行校验(参数完整性,sku_id商品是否存在,商品的库存)
        2. 修改用户的购物车记录
            2.1 如果用户已登录,修改redis中对应的购物车记录
            2.2 如果用户未登录,修改cookie中对应的购物车记录
        3. 返回应答,购物车记录修改成功
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id商品是否存在,商品的库存)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取校验之后的数据
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 获取user
        try:
            # 调用request.user会触发DRF框架认证过程
            user = request.user
        except Exception:
            user = None

        # 2. 修改用户的购物车记录
        if user and user.is_authenticated:
            # 2.1 如果用户已登录,修改redis中对应的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')

            # 修改redis hash中商品id对应数量count
            cart_key = 'cart_%s' % user.id
            redis_conn.hset(cart_key, sku_id, count)

            # 修改redis set中勾选的商品id
            cart_selected_key= 'cart_selected_%s' % user.id

            if selected:
                # 勾选
                redis_conn.sadd(cart_selected_key, sku_id)
            else:
                # 取消勾选
                redis_conn.srem(cart_selected_key, sku_id)

            return Response(serializer.validated_data)
        else:
            # 2.2 如果用户未登录,修改cookie中对应的购物车记录
            response = Response(serializer.validated_data)

            # 获取cookie中的购物车数据
            cookie_cart = request.COOKIES.get('cart') # None

            if cookie_cart is None:
                # 购物车中无数据
                return response

            # 解析cookie中的购物车数据
            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>'
            #     },
            #     ...
            # }
            cart_dict = pickle.loads(base64.b64decode(cookie_cart)) # {}
            if not cart_dict:
                # 字典为空,购物车无数据
                return response

            # 修改购物车数据
            cart_dict[sku_id] = {
                'count': count,
                'selected': selected
            }

            # 3. 返回应答,购物车记录修改成功
            # 设置cookie中购物车数据
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart', cart_data, max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #27
0
    def put(self, request):
        """
        购物车记录修改:
        1. 获取参数并进行校验(sku_id对应的商品是否存在,商品库存是否足够)
        2. 修改用户的购物车记录
            2.1 如果用户已登录,在redis中修改用户的购物车记录
            2.2 如果用户未登录,在cookie中修改用户的购物车记录
        3. 返回应答,购物车记录修改成功
        """
        # 1. 获取参数并进行校验(sku_id对应的商品是否存在,商品库存是否足够)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取校验之后的数据
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # request.user会触发DRF框架的认证过程,但是此处的代码是我们自己调用的,所有自己进行处理
        try:
            user = request.user
        except Exception as e:
            user = None

        # 2. 修改用户的购物车记录
        if user is not None and user.is_authenticated:
            # 2.1 如果用户已登录,在redis中修改用户的购物车记录
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()

            # 在redis hash修改用户购物车中对应商品数量count
            cart_key = 'cart_%s' % user.id

            # hset(key, field, value): 设置hash中指定属性field的值为value
            pl.hset(cart_key, sku_id, count)

            # 在redis set修改用户购物车中勾选状态
            cart_selected_key = 'cart_selected_%s' % user.id
            if selected:
                # 勾选
                # sadd(key, *members): 向set集合中添加元素,元素是唯一的
                pl.sadd(cart_selected_key, sku_id)
            else:
                # 取消勾选
                # srem(key, *members): 从set集合中移除元素,有则移除,无则忽略
                pl.srem(cart_selected_key, sku_id)

            pl.execute()

            # 返回响应
            return Response(serializer.data)
        else:
            response = Response(serializer.data)
            # 2.2 如果用户未登录,在cookie中修改用户的购物车记录
            # 获取原始的cookie购物车数据
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart is None:
                # 购物车无数据
                return response

            # 解析cookie购物车数据
            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>'
            #     },
            #     ...
            # }
            cart_dict = pickle.loads(base64.b64decode(cookie_cart))  # {}

            if not cart_dict:
                # 字典为空,购物车无数据
                return response

            # 修改用户的购物车数据
            cart_dict[sku_id] = {'count': count, 'selected': selected}

            # 3. 返回应答,购物车记录修改成功
            cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
            response.set_cookie('cart',
                                cart_data,
                                max_age=constants.CART_COOKIE_EXPIRES)
            return response
Exemple #28
0
    def put(self, request):
        """
        购物车记录修改:
        1. 获取参数并进行校验(参数完整性,sku_id商品是否存在,count是否大于库存)
        2. 获取user并处理
        3. 修改用户的购物车记录
            3.1 如果用户已登录,修改redis中的购物车记录
            3.2 如果用户未登录,修改cookie中的购物车记录
        4. 返回应答
        """
        # 1. 获取参数并进行校验(参数完整性,sku_id商品是否存在,count是否大于库存)
        serializer = CartSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)

        # 获取参数
        sku_id = serializer.validated_data['sku_id']
        count = serializer.validated_data['count']
        selected = serializer.validated_data['selected']

        # 2. 获取user并处理
        try:
            user = request.user
        except Exception as e:
            user = None

        # 3. 修改用户的购物车记录
        if user is not None and user.is_authenticated:
            # 3.1 如果用户已登录,修改redis中的购物车记录
            # 获取redis链接
            redis_conn = get_redis_connection('cart')
            pl = redis_conn.pipeline()

            # 修改redis用户购物车中商品id和数量count hash
            cart_key = 'cart_%s' % user.id
            # hset(key, field, value): 将hash中指定属性field的值设置为value
            pl.hset(cart_key, sku_id, count)

            # 修改redis用户购物车中商品的勾选状态 set
            cart_selected_key = 'cart_selected_%s' % user.id

            if selected:
                # 勾选
                # sadd(key, *members)
                pl.sadd(cart_selected_key, sku_id)
            else:
                # 不勾选
                # srem(key, *members): 从set中移除元素,如果元素不存在,直接忽略
                pl.srem(cart_selected_key, sku_id)

            pl.execute()
            return Response(serializer.data)
        else:
            # 3.2 如果用户未登录,修改cookie中的购物车记录
            response = Response(serializer.data)
            # 尝试从cookie中获取原始的购物车数据
            cookie_cart = request.COOKIES.get('cart')  # None

            if cookie_cart is None:
                return response

            # 解析cookie中购物车数据
            # {
            #     '<sku_id>': {
            #         'count': '<count>',
            #         'selected': '<selected>'
            #     },
            #     ...
            # }
            cart_dict = pickle.loads(base64.b64decode(cookie_cart))  # {}

            if not cart_dict:
                return response

            # 修改用户购物车对应商品的数量和勾选状态
            if sku_id in cart_dict:
                cart_dict[sku_id] = {'count': count, 'selected': selected}

                # 设置cookie
                cart_data = base64.b64encode(pickle.dumps(cart_dict)).decode()
                response.set_cookie('cart',
                                    cart_data,
                                    expires=constants.CART_COOKIE_EXPIRES)

            # 4. 返回应答
            return response
Exemple #29
0
 def delete_item(self, request, pk):
     cart_item = self.get_object()
     cart_item.delete()
     cart_serializer = CartSerializer(cart_item.cart)
     return Response(cart_serializer.data, status=status.HTTP_200_OK)
Exemple #30
0
 def clear(self, request, pk=None):
     cart = self.get_object()
     self.clear_cart(cart)
     cart = self.get_object()
     return Response(CartSerializer(cart).data)