장바구니 API구현
회고록
회원가입과 로그인 API가 아닌 새롭게 처음부터 API를 구현하게 됬다.
사용자가 어떤 Flow로 장바구니에 상품을 담는지 생각해서 API를 구현을 했다.
먼저 상품에서 원하는 상품에 대해서 장바구니에 추가(POST)한다.
장바구니에 들어가 상품을 확인(GET)한다. 원하는 상품에 대한 수량을 변경(PETCH)한다. 잘못 선택한 상품을 삭제(DELETE)한다.
장바구니에 대한 CRUD를 구현했다.
맨 바닥부터 시작해서 하나씩 구현해갔다. 다른 사람들이 어떻게 구현했는지 보고서 하고 싶은 생각도 들었지만, 우선은 내가 아는 범위내에서 최대한 구현해보려고 노력했다.
우선은 결과적으로 혼자힘으로 장바구니를 구현했다. 하지만 단순히 기능을 위한 코드를 구현하다보니, 주먹구구식으로 코드를 구현한게 보였다.
어떤 오류를 해결하기 위해 임시방편으로 만든 코드가 된 것이다. 그러다보니 코드에 대한 가독성도 떨어지고, 나밖에 모르는 코드가 되버렸다.
멘토님의 리뷰를 받고, 코드를 구현함에 있어 기능만이 중요한 요소가 아님을 느꼈다. 기능도 중요하지만 그 외 다른 사람에게도 보기 좋은 코드가 되어야 겠다고 생각했다.
장바구니 GET
import json
from django.db import transaction
from django.http import JsonResponse
from django.views import View
from carts.models import Cart
from products.models import *
from core.utils import login_decorator
class CartView(View):
@login_decorator
def get(self, request):
cart_list = Cart.objects.select_related('product','user','size','graind')\
.prefetch_related('product__productimage_set')\
.filter(user=request.user)
result = [{
"cart_id" : cart.id,
"id" : cart.product.id,
"user" : cart.user.name,
"product" : cart.product.name,
"size" : cart.size.name,
"price" : cart.size.price,
"graind" : cart.graind.type,
"quantity" : cart.quantity,
"image" : cart.product.productimage_set.all()[0].url,
"is_checked" : False
} for cart in cart_list]
return JsonResponse({'MESSAGE': result}, status=200)
장바구니 POST
@login_decorator
@transaction.atomic()
def post(self, request):
try:
datas = json.loads(request.body)
user = request.user
product_id = datas["product_id"]
products = datas["product"]
target_product = Product.objects.get(id = product_id)
for product in products:
quantity = product["quantity"]
graind = target_product.graindbyproduct_set.get(grainding_id = product["graind"]).grainding
size = target_product.size_set.get(name = product["size"])
cart, is_bool = Cart.objects.get_or_create(
user = user,
product = target_product,
graind = graind,
size = size,
defaults = {'quantity': quantity}
)
if not is_bool :
cart.quantity += quantity
cart.save()
return JsonResponse({"MESSAGE": "TEST"}, status=200)
except KeyError:
return JsonResponse({"MESSAGE": "KEYERROR"}, status=400)
except Size.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_SIZE"}, status=400)
except Product.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_PRODUCT"}, status=400)
except Grainding.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_GRAINDING"}, status=400)
except json.JSONDecodeError:
return JsonResponse
except GraindByProduct.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_GRAINDING"}, status=400)
장바구니 PETCH
@login_decorator
def patch(self,request):
try:
data = json.loads(request.body)
user = request.user
cart = Cart.objects.get(id=data["cart_id"], user=user)
quantity = data["quantity"]
if quantity <= 0:
return JsonResponse({'MESSAGE' : f'INVALID VALUE : {quantity} '}, status=400)
cart.quantity = quantity
cart.save()
return JsonResponse({"MESSAGE": "PATCH_SUCCESS"}, status=200)
except KeyError:
return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)
except Cart.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_CART"}, status=400)
장바구니 DELETE
@login_decorator
def delete(self, request):
try:
datas = json.loads(request.body)
user = request.user
if datas.get("is_bool"):
Cart.objects.filter(user=user).delete()
elif datas.get("cart_id"):
for data in datas["cart_id"]:
Cart.objects.get(id=data, user=user).delete()
return JsonResponse({"MESSAGE": "DELETE_SUCCESS"}, status=200)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status=400)
except Cart.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOTEXIST_CART"}, status=400)