프로젝트 1차 [오설록 클론코딩]

인간·2022년 7월 24일
1

장바구니 구현

import json
from json.decoder           import JSONDecodeError

from django.views           import View
from django.http            import JsonResponse
from django.core.exceptions import MultipleObjectsReturned

from cart.models            import Cart
from users.models           import User
from products.models        import Product
from core.utils             import login_decorator

class CartView(View) :
    @login_decorator
    def post(self, request) :
        try :
            data       = json.loads(request.body)
            user       = request.user
            product_id = data['product_id']
            quantity   = data['quantity']

            if not Product.objects.filter(id=product_id).exists():
                return JsonResponse({'message':'PRODUCT_NOT_EXIST'}, status=400)

            if quantity <= 0:
                return JsonResponse({'message':'QUANTITY_ERROR'}, status=400)
        
            cart, is_created  = Cart.objects.get_or_create(
                user_id       = user.id,
                product_id    = product_id
            )
            cart.quantity += quantity
            cart.save()
            
            if is_created == 0 :
                return JsonResponse({'message': 'UPDATE_SUCCESS'}, status=200)
            return JsonResponse({'message': 'CREATE_SUCCESS'}, status=201)
            
        except Cart.DoesNotExist :
            return JSONDecodeError({'message':'INVAILD_CART'}, status=400)
        except JSONDecodeError :
            return JsonResponse({'message':'JSON_DECODE_ERROR'}, status=400)
        except KeyError :
            return JsonResponse({'message':'KEY_ERROR'}, status=400)

    @login_decorator
    def get(self, request):
        user  = request.user.id
        carts = Cart.objects.filter(user_id=user)
        
        result = [{
            'username'        : user,
            'cart_id'         : cart.id,
            'product_id'      : cart.product.id,
            'title'           : cart.product.title,
            'quantity'        : cart.quantity,
            'price'           : cart.product.price,
            'thumbnail_images': cart.product.thumbnail_images.first().url,
            'discount'        : cart.product.discount,
            'stock'           : cart.product.stock
            
        } for cart in carts]
     
        return JsonResponse({"result":result}, status = 200)
    
    @login_decorator
    def delete(self, request):
        try:    
            data    = json.loads(request.body)
            user    = request.user
            cart_id = data['cart_id']
            cart    = Cart.objects.get(id=cart_id, user=user)

            cart.delete()
            return JsonResponse({'message':'DELETED'}, status=200)

        except MultipleObjectsReturned :
            return JsonResponse({'message':'MULTIPLE_OBJECTS_RETURNED'}, status=400)
        except ValueError :
            return JsonResponse({'message':'VAULE_ERROR'}, status=400)

    @login_decorator
    def patch(self, request) :
        try :
            data     = json.loads(request.body)
            user     = request.user.id
            cart_id  = data['cart_id']
            quantity = data['quantity']
           
            if quantity <= 0:
                return JSONDecodeError({'message':'QUANTITY_ERROR'}, status=400)

            cart = Cart.objects.get(id=cart_id, user=user)

            cart.quantity = data['quantity']
            cart.save()
            return JsonResponse({'quantity':cart.quantity}, status=200)

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

일단 장바구니의 데코레이터를 불러와 로그인 인증/인가를 검증하고

POST

를 하는건 전에 배웠던 부분이라 어려움이 없었는데. 수량부분의 좀 어려움이 있었다. 장바구니안에 데이터가 생성되면 예를들어
1번의 상품과 1번의 유저가 장바구니에 담으면 데이터가 생성되면 1번ID의 카트가 생긴다. 근데 만약에 이 사람이 나중에 상품을 하나를 더 추가하려고
추가를 누르면 데이터가 하나 더 생기는게 아니라 수량만 변경되야한다.

그래서 처음에는 시행착오가 엄청났는데.. 어떻게하지 하다가. 우연히 블로그 글을 봐서 get_or_created 라는 메소드를 알게되었다.

여기서 정말 재밌는건 created 값이 불린인데 생성이되면 1을 반환하고 정보를 가져오면 0으로 표기한다. 헷갈리수 있어서 이렇게 적었다.

그래서 return 값을 처음엔 그냥 201 성공이라는 문구를 제이슨으로 리턴해주었는데 멘토님이 구분하라해서 if==1이면 업데이트 되었다로 바꿔주었다.

GET

이거또한 해봤던 것이라 크게 어렵지는 않았다.
다만 썸네일 이미지를 불러올때 first라는 메소드를 처음 사용 해 보았는데
이 메소드는 하나하나 읽어오는거라 만약에 첫번쨰가 없어버리면 NONE처리되고
뒤에껀 나오지 않는다는걸 알았다 반복적으로 NONETYPE 에러라는게 낫었다.
옆에있는 동기님의 도움으로 해결함.

profile
잇츠미

0개의 댓글