Project : 정육각 클론 - Cart 쿼리셋 및 View 작성

Joey Lee·2020년 6월 3일
1

Django

목록 보기
16/23

정육각 클론사이트의 Cart View를 만들기 위한 쿼리셋 테스트 과정과 최종코드를 아래와 같이 정리해 봅니다.

1. Queryset 테스트

1) Cart 정보 뿌리기 위한 Get 함수 테스트

# 1번 고객의 신규 카트 생성 (카트 아이디 2번 생성)
> Cart.objects.create(customer_id=1) 
<Cart: Cart object (2)>

# 카트 아이디 2번에 상품 아이디 5번 신규 생성
> CartItem.objects.create(cart_id=2, product_id=5, selected_option_id=11, quantity=2)  
<CartItem: CartItem object (2)>

# 카트 아이디 3번에 상품 아이디 3번 신규 생성
> CartItem.objects.create(cart_id=2, product_id=3, selected_option_id=9, quantity=1)   
<CartItem: CartItem object (3)>

> cart = Cart.objects.filter(customer_id=1)
> cart
<QuerySet [<Cart: Cart object (1)>, <Cart: Cart object (2)>]>

# 1번 고객의 마지막 카트 cart_last 변수에 담기
> cart_last = Cart.objects.filter(customer_id=1).last()       
> cart_last
<Cart: Cart object (2)>
> carts = 

# 1번고객의 마지막 카트에 담긴 카트 아이템들을 carts 변수에 담기
Cart.objects.prefetch_related('cartitem_set').get(id=cart_last.id).cartitem_set.all()   
> carts
<QuerySet [<CartItem: CartItem object (2)>, <CartItem: CartItem object (3)>]>

# 1번 고객의 마지막 카트에 담긴 아이템들을 data 변수에 담기
> data = [{"name" : Product.objects.get(id=cart.product_id), "sales_price" : Product.objects.get(id=cart.product_id), "quantity" : cart.quantity} for cart in carts]       
> data
[{'name': <Product: 초신선 무항생제 다짐육 한우 우둔>, 'sales_price': <Product: 초신선 무항생제 다짐육 한우 우둔>, 'quantity': 2}, {'name': <Product: 초신선 동물복지 무항생제 유정란>, 'sales_price': <Product: 초신선 동물복지 무항생제 유정란>, 'quantity': 1}]

> data = [{"name" : Product.objects.get(id=cart.product_id).name, "sales_price" : Product.objects.get(id=cart.product_id).sales_price, "quantity" : cart.quantity} for cart in carts]

> data
[{'name': '초신선 무항생제 다짐육 한우 우둔', 'sales_price': Decimal('13200.00'), 'quantity': 2}, {'name': '초신선 동물복지 무항생제 유정란', 'sales_price': Decimal('6600.00'), 'quantity': 1}]

# JSON으로 넘겨줄 최종 data 셋 완성
> jsd = {'data':list(data)}  
> jsd
{'data': [{'name': '초신선 무항생제 다짐육 한우 우둔', 'sales_price': Decimal('13200.00'), 'quantity': 2}, {'name': '초신선 동물복지 무항생제 유정란', 'sales_price': Decimal('6600.00'), 'quantity': 1}]}

2) Cart : 카트 등록/수정 위한 Post 함수 테스트

# 1번 고객의 마지막 카트 객체 cart_p 변수에 담기
> cart_p = Cart.objects.filter(customer_id=1).last()

# 마지막 카트아이디를 가지고 있는 카트아이템들을 cartdetail변수에 담기 => 2개 상품이 나옴.
> cartdetail = CartItem.objects.filter(cart_id=cart_p.id).       
> cartdetail
<QuerySet [<CartItem: CartItem object (2)>, <CartItem: CartItem object (3)>]>

# 마지막 카트아이디를 가지고 있는 카트아이템 중 특정 상품 아이디를 가지고 있는 1개만 cartdetail에 담기
> cartdetail = CartItem.objects.filter(cart_id=cart_p.id, product_id=3)   
> cartdetail
<QuerySet [<CartItem: CartItem object (3)>]>

# 카트 아이템 수량을 1개에서 5개로 수정하기
> cartdetail.update(quantity=5)           
> cartdetail[0].quantity                            
5

# 새로운 카트 아이템 추가하기
> new_item = CartItem(cart_id=2, product_id=2, selected_option_id=8, quantity=3)   
>>> new_item.save()

# 마지막 카트 객체 new_cart에 담기 
> new_cart = Cart.objects.filter(customer_id=1).last()    
> carts = new_cart.cartitem_set.all()                  > carts
<QuerySet [<CartItem: CartItem object (2)>, <CartItem: CartItem object (3)>, <CartItem: CartItem object (4)>]>

# 마지막 카트 객체의 카트 아이템 정보를 new_data에 담기
> new_data = [{"name" : Product.objects.get(id=cart.product_id).name, "sales_price" : Product.objects.get(id=cart.product_id).sales_price, "quantity" : cart.quantity} for cart in carts]                 
> new_data
[{'name': '초신선 무항생제 다짐육 한우 우둔', 'sales_price': Decimal('13200.00'), 'quantity': 2}, {'name': '초신선 동물복지 무항생제 유정란', 'sales_price': Decimal('6600.00'), 'quantity': 5}, {'name': '초신선 닭볶음탕', 'sales_price': Decimal('4900.00'), 'quantity': 3}]
>>> new_jsd = {'data': list(new_data)}
>>> new_jsd
{'data': [{'name': '초신선 무항생제 다짐육 한우 우둔', 'sales_price': Decimal('13200.00'), 'quantity': 2}, {'name': '초신선 동물복지 무항생제 유정란', 'sales_price': Decimal('6600.00'), 'quantity': 5}, {'name': '초신선 닭볶음탕', 'sales_price': Decimal('4900.00'), 'quantity': 3}]}

2. CartView 코드

class CartView(View):    
    @login_decorator
    def post(self, request):
        try:
            data        = json.loads(request.body)
            customer_id = request.customer.id

            if Cart.objects.filter(customer_id=customer_id).exists():       # 해당 고객의 카트가 존재하면 가져옴
                cart = Cart.objects.get(customer_id=customer_id)
            else: # 해당 고객에게 카트가 없으면 카트를 신규로 생성하고, order_status_id를 부여
                cart = Cart.objects.create(customer_id=customer_id, cart_status_id=1)             

            cart_items = CartItem.objects.filter(cart_id=cart.id, product_id=data['product_id'])

            if cart_items.exists():
                cart_items.update(
                    quantity = data['quantity']
                )
                return HttpResponse(status=200)
            
            else:
                CartItem(
                    cart_id            = cart.id,
                    product_id         = data['product_id'],
                    selected_option_id = data['selected_option_id'],
                    quantity           = data['quantity']
                ).save()
                return HttpResponse(status=200)

        except KeyError:
            return HttpResponse(status=400)

    @login_decorator
    def get(self, request):
        try:
            customer_id = request.customer.id
            
            cart       = Cart.objects.get(customer_id=customer_id, cart_status_id=1)
            cart_items = CartItem.objects.select_related('product', 'selected_option').filter(cart_id=cart.id)

            total_amount = 0
            for cart_item in cart_items:
                total_amount += cart_item.product.sales_price * cart_item.quantity
            
            delivery_cost = 0
            expected_amount = total_amount + delivery_cost

            cart_items = [
                {
                    'cart_item_id'    : cart_item.id,
                    'product_id'      : cart_item.product.id,
                    'name'            : cart_item.product.name,
                    'sub_img_url'     : cart_item.product.sub_img_url,
                    'selected_option' : OptionItems.objects.get(id=cart_item.selected_option_id).name,
                    'sales_price'     : cart_item.product.sales_price,
                    'per_quantity'    : cart_item.product.sales_price_comment.split('(')[1].replace(')', ' 기준'),
                    # sales_price_comment 기준가 xx원 (600g) 에서 600g 파싱한 뒤,' 기준' 멘트 추가 
                    'quantity'        : cart_item.quantity
                } for cart_item in cart_items
            ]

            cart = [
                {
                    'cart_id'         : cart.id,
                    'total_amount'    : total_amount,
                    'delivery_cost'   : delivery_cost,
                    'expected_amount' : expected_amount
                }
            ]

            return JsonResponse({'cart_items' : cart_items, 'cart' : cart}, status=200)
        except Cart.DoesNotExist:
            return JsonResponse({'message' : 'CART_NOT_EXIST'}, status=200)

    @login_decorator
    def delete(self, request):
        data        = json.loads(request.body)
        customer_id = request.customer.id

        cart = Cart.objects.get(customer_id=customer_id)
        CartItem.objects.get(cart_id=cart.id, product_id=data['product_id']).delete()

        return HttpResponse(status=200)

3. 테스트 결과

1) Cart 상품 추가/수정 - POST

2) Cart 상품 보기 - GET

3) Cart 상품 삭제 - DELETE

profile
안녕하세요!

0개의 댓글