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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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')
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)
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)
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)
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)
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')
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)
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)
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
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
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
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
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
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
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
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
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
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
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)
def clear(self, request, pk=None): cart = self.get_object() self.clear_cart(cart) cart = self.get_object() return Response(CartSerializer(cart).data)