[BAGETTT] 장바구니 API

LILO Ghim·2021년 12월 12일
0

CartView

PackagesListView로 너무 고생(?)아닌 고생을 해서 그랬는지 리팩토링 전 단계의 장바구니 API는 신나게 쉘 찍어가며 만들었다(엉망진창). 물론 라이브코드 시간에 촥촥촥 날라갔지만,,,

처음 사용해 본 개념들은,
1) get_or_create
2) .save()
3) aggreagate / sum
4) __in

post

의외의 복병이 있었는데, 바로 quantity와 price
이 둘을 create 안에 넣어 놨더니 테이블이 계속 생성,,, 당연하지,,,
수량과 가격까지도 조건에 포함이 되는 요소인 것,
같은 상품을 1개씩 계속 추가 했더니 같은 상품이 2개에서 증가를 하지 않고 테이블을 계속 생성 하는 것,,,,,

  • 첫번째 해결방법은 default를 주는 것
    defaults를 주고 입력하는 값으로 지정을 했더니 > 이제는 수량과 가격이 2배씩 증가,,,,, 코드 리뷰 때도 몰랐,,,,,

  • (이 사실을 놀랍게도 최종 mergy 직전에 알았;;;;;) 결과적으로! modeling의 defualt가 문제였던 것!!! 결국, 마지막까지 modeling을 수정하고, 마이그레이션, 마이그레이트 지옥,,,,,

class CartView(View):
    @decorator
    def post(self, request):
        try:
            data            = json.loads(request.body)
            user            = request.user
            quantity        = data["quantity"]
            price           = data["price"]
            package_id      = data["package_id"] 
            shipping_option = data["shipping_option"]
            option          = Option.objects.get(shipping_option=shipping_option).id 
            
            if int(quantity) < 1 :
                return JsonResponse({'message':'DESELECTED_QUANTITY'}, status = 400)
            
            cart, created = Cart.objects.get_or_create(
                user            = user,
                package_id      = package_id,
                defaults        = {
                    'shipping_option_id' : option
                }
            )
            cart.quantity += quantity
            cart.price    += price
            cart.save()
            
            return JsonResponse({'result':'ADD_CART'}, status = 201)
        
        except ValidationError as e:
            return JsonResponse({'message':e.message}, status = 400)

        except KeyError:
            return JsonResponse({'message':'KEY_ERROR'}, status = 400)

GET

total_price를 front_end에서 cart의 get 요청시에만 보여주게 하는 것이 get의 point였다.
aggregate를 써보기 위해 모델링때부터 고려했던,,,

@decorator
    def get(self, request):
        try:
            user        = request.user
            carts       = Cart.objects.filter(user = user.id)
            total_price = carts.values('price').aggregate(total_price=Sum('price'))
            
            result=[{
                'total_price' : total_price,
                'cart'        : [{
                    'id'        : cart.id,
                    'image'     : cart.package.thumbnail_image, 
                    'name'      : cart.package.name, 
                    'price'     : cart.price,
                    'quantity'  : cart.quantity,
                    'option'    : cart.shipping_option.shipping_option 
                } for cart in carts]
            }]

            return JsonResponse({'result':result}, status = 200)

        except ValidationError as e:
            return JsonResponse({'message':e.message}, status = 401)

DELETE / 부분삭제

cart_id를 front-end로부터 list로 받아 장바구니 상품별 삭제가 가능하게 했던 것도 모두 PackageListView가 있었기에 가능했던,,,

@decorator
    def delete(self, request):
        try:
            data      = json.loads(request.body)
            cart_list = data['id']
            carts     = Cart.objects.filter(id__in=cart_list)

            carts.delete()

            return JsonResponse({'result':'DELETE_CART'}, status = 200)
        
        except ValidationError as e:
            return JsonResponse({'message':e.message}, status = 401)

PATCH

장바구니페이지에서 나갔다가 다시 들어와도 직전의 정보가 저장되어 front-end에게 보여줄 수 있도록 장바구니에서 수량을 수정할 때는 수정된 수량만 DB에 저장하고, 가격은 DB에서 계산하여 저장만하고 있다가(front-end와 통신없음), 요청시에만 수량과 가격을 응답할 수 있도록 했다.

@decorator
    def patch(self, request): 
        try:
            data        = json.loads(request.body)
            quantity    = data['quantity']
            id          = data['id']
            
            if int(quantity) < 1:
                return JsonResponse({'messages':'DESELECTED_QUANTITY'}, status = 400)

            cart  = Cart.objects.get(id=id)
            price = cart.package.price
            
            cart.quantity = quantity
            cart.price    = Decimal(int(cart.quantity) * int(price))
            cart.save()    
                
            return JsonResponse({'result':'QUANTITY_IN_CART'}, status = 200)
        
        except ValidationError as e:
            return JsonResponse({'message':e.message}, status = 401)
profile
킴릴로

0개의 댓글