21.3.24

커피 내리는 그냥 사람·2021년 3월 24일
0

위코드 1차 프로젝트

목록 보기
10/13

1차 프로젝트 9일차

1. 스탠딩 미팅:

  1. 프론트 / 백엔드 일정 공유 : 스크럼 방식에 따른 2차 스프린트 완료 전까지 (~목) 주요 기능 합쳐보기 및 완성에 주력.
  2. 오늘 할 일 :
  • LOVE 팀 단위 상담

    팀, 포지션 간 의사소통 중요. 2차 프로젝트에서도 마찬가지로 발표가 중요. 발표까지가 프로젝트.

  • 장바구니 마무리 / 결제 마무리(택향님)
  • 쿠폰 마무리(나)
  • 프론트 메인 페이지, 장바구니 기능구현 등 완료 후 최대한 맞춰보기

2. 리뷰 :

wishlist(찜하기)

  1. "Wishlist POST 에서 찜하려고 하는 제품 정보만 객체로 받으면 되는데 굳이 results 라는 변수에 리스트를 할당하여 그안에 객체로 받을 이유가 없습니다"
            results = json.loads(request.body)['results']
            user_id = request.user.id

            for result in results:
                product_id              = result['product_id']
                quantity                = result['quantity']
                product_option_id       = result['product_option_id']
                product_option_quantity = result['product_option_quantity']
  • 불필요한 for문 축소하기
  • 해결 방법 : 반복문 없앤 뒤 results로 넣은 변수를 직접 다 데이터로 넣음.
  1. GET 메서드에서는 JSONDecodeError, KeyError가 나지 않는다. 왜냐면 해당 뷰에서 클라이언트에게 받는 키가 존재하지 않기 때문이다.

coupon

  1. 한 뷰에 여러 post가 들어갈 수 없다.

3. coupon view 짜기

제 하던 것에 수정하기

  1. 쿠폰 등록 뷰
class CouponRegistryView(View):
    @transaction.atomic
    # 연속적인 작업이므로 트렌젝션 아토믹
    @auth_check
    # 모든 작업에는 유저의 토큰이 가야한다.
    def post(self, request):
        try:
            data           = json.loads(request.body)
            name           = data['name']
            discount_price = data['discount_price']
            issue_date     = data['issue_date']
            expire_date    = data['expire_date']
            # 쿠폰을 만들기 위해 받는 자료
            
            sub_category   = SubCategory.objects.get(name=data['sub_category_name'])
            
            coupon = Coupon.objects.create(
                name                = name,
                discount_price      = discount_price,
                issue_date          = issue_date,
                expire_date         = expire_date
            )
            # 쿠폰 만들기
            
            coupon_sub_category = CouponSubCategory.objects.create(coupon=coupon, sub_category=sub_category)
            # 쿠폰의 서브카테고리도 따로 뷰 만들지 않고 만들 수 있다.
            
            return JsonResponse({'message' : 'SUCCESS'}, status=201)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status=400)
        except JSONDecodeError:
            return JsonResponse({'message' : 'JSON_DECODE_ERROR'}, status=400)    
  1. 쿠폰과 유저의 관계 뷰
class UserCouponView(View):
    @transaction.atomic
	@auth_check
    # 마찬가지로 트랜잭션, 데코레이터 토큰 처리
    def post(self, request):
        try:
            data     = json.loads(request.body)
            coupon   = Coupon.objects.get(id=data['coupon_id']).id
            user     = request.user.id
            # 데코레이터 처리로 인한 변경
            quantity = data['quantity']

            
            user_coupon, is_created = UserCoupon.objects.get_or_create(
            coupon_id = coupon,
            user_id   = user,
            defaults  = {'quantity' : quantity}
            )
            if not is_created:
                user_coupon.quantity += data['quantity']
                user_coupon.save()
                # 쿠폰도 unique_toghether 되어 있는 상황
                # 데이터에 직접 수량이 변하는 것을 입력해야 하므로 get_or_create 및 if문 처리 ; 저번 블로그 설명 참고
            return JsonResponse({'message' : 'SUCCESS'}, status=201)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status=400)
        except JSONDecodeError:
            return JsonResponse({'message' : 'JSON_DECODE_ERROR'}, status=400)

여기까지 쿠폰을 등록하고 유저와 관계를 맺고나면 다음과 같은 상황이 주어진다.

  • 만든 쿠폰을 유저가 가지고 있는 것과 서브 카테고리에 있는 것을 비교해, 두 조건이 일치하면 결제하기에서 모두 비춰지게 한다.
  1. 쿠폰 비춰주는 뷰
  • 고민한 점 : 유저가 가진 쿠폰과 연관된 쿠폰을 어떻게 이어야 할지 고민
  • 과정 :
    유저가 가진 쿠폰을 모두 가져온다.(쿠폰 아이디) -> 서브카테고리마다 연결된 쿠폰을 모두 가져온다(쿠폰 아이디) -> 이 두 리스트를 비교한다 -> 같은 리스트를 찾으면 리스트로 만들어준다 -> 이걸 한글로 출력시킨다
  • 사용된 개념 : 역참조 / 리스트 컴프리핸션 / for반복문 / 어제 배운 메서드 활용한 값 꺼내오기 / json has_header 에러
import json

from django.db       import transaction
from django.db.utils import DataError
from django.views import View
from django.http  import JsonResponse

from product.models      import (
                          Category, SubCategory, Product,
                          ProductImage, Option, ProductOption
                        )
from user.models      import User, Coupon, UserCoupon
from order.models     import Order
from utils.decorators import auth_check


class ApplyCouponView(View):
    @auth_check
    @transaction.atomic()
    # 마찬가지로 트랜젝션 및 토큰
    def post(self, request):
        try:
            data       = json.loads(request.body)
            user_id    = request.user.id
            product_id = data['product_id']
            # 먼저 유저 정보를 토큰으로 가져오고 프론트엔드가 유일하게 주는 product_id 하나를 구한다. 예시로 15번을 사용했다.

            user_coupons     = UserCoupon.objects.filter(user_id = user_id)
            user_coupon_list = [user_coupon.coupon_id for user_coupon in user_coupons]
            # 쉘을 찍어서 확인해본 결과 유저 아이디를 먼저 필터링한 후(3으로 했다.) -> 오브젝트로 나온 값에 대해서 coupon_id값만 리스트 컴프리핸션으로 리스트로 만든다.

            sub_category             = Product.objects.get(id=product_id).sub_category
			# 내가 아는 정보는 product_id 하나뿐이다. 따라서 이를 최대한 이용해서 서브 카테고리까지 뽑아낸다.
            sub_category_coupons     = sub_category.couponsubcategory_set.all()
			# 쿠폰으로 가려면 역참조를 해야한다. 역참조 공식에 따라 서브카테고리로 모든 쿠폰 서브카테고리의 내용을 가져온다.
            sub_category_coupon_list = [sub_category_coupon.coupon_id for sub_category_coupon in sub_category_coupons]
            # 이를 coupon_id값만 리스트 컴프리헨션으로 리스트를 만든다.

            result = []
            for i in user_coupon_list:
                if i in sub_category_coupon_list:
                    result.append(i)
             # 이후 두 값을 비교하는데 for 문을 통해 있는지 없는지 확인 후 append 해준다.
            
            coupon_name = []
            for j in result:
                coupon = Coupon.objects.get(id=j)
                coupon_name.append(coupon.name)
            # 그렇게 나온 공통적인 coupon_id를 구했다면 반대로 그 name을 구해준다.
            # 여기서 주의할 점 : return을 여기서하면 has_heager에러가 난다. 즉 json을 리턴할 수 없기 때문.
            return JsonResponse({'message' : 'SUCCESS', 'coupon_name' : coupon_name}, status=201)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status=400)
        except JSONDecodeError:
            return JsonResponse({'message' : 'JSON_DECODE_ERROR'}, status=400) 

for문이 너무 많다. 효율적인 코드라고는 할 수 없어 멘토님과 상의 결과 나중에 더 고민해길 바라는 코드였다. 오늘 반나절 정도 고민한 코드고 많이 물어보며 한 만큼 값진 결과물이었다. 이제 프론트랑 맞춰보면 되겠다.

  1. (추가) 서브카테고리를 리스트로 하여 여러 서브 카테고리가 다양한 쿠폰에 매핑되게 하는 것.
  • 무슨소리인가 하면 쿠폰이 생성될 때 한 제품군에만 되는게 아니라 여러 제품군에 내가 원하는거에 매핑시키는 것.

    예를 들어 '할인쿠폰1, 2, 3 등 여러 개가' 이 생겼는데 양말 말고도 덧신, 신발에도 적어 넣기만 하면 주르륵 생기는 것.

  • 해당 부분 코드(user/views.py)

            coupons = Coupon.objects.all()
            for coupon in coupons:
                coupon_sub_category = CouponSubCategory.objects.create(
                    coupon=coupon, 
                    sub_category=sub_category
                    )
  • 고민한 것 : 분명 for loop을 해줘야 하는데 어떤 것을 기준으로 for loop을 해줘야할지 몰라 초반에는 get_or_create, 그냥 for loop 을 돌렸는데 우연히 장고 쉘에서 coupon을 중심으로 돌렸더니 데이터가 생기는 것을 목격.

    하지만 coupon이 iterable하지 않기 때문에 다른 방법이 필요.

  • 해결 : 결론은 쿠폰을 제대로 정의해주지 않았기 때문. 그냥 오브젝트일 뿐인 것을 정의해줄 "coupons = Coupon.objects.all()"를 붙인 뒤 해줬더니 완벽하게 적용되었다.(쿼리셋을 루프해주는 방법을 찾아봄)


  • 쿼리셋을 loop 하는 완벽한 방법
    참고 사이트

4. 내일 할 일

  • wishlist 뷰 리뷰 마무리
  • 쿠폰 리뷰받기
  • 메인화면에 정보 출력(현재 택향님 진행중)
  • 주문화면에서 내가 만든 쿠폰도 연결하기
  • 전체적인 스크럼 방식으로 홈페이지 완성도 확인
profile
커피 내리고 향 맡는거 좋아해요. 이것 저것 공부합니다.

0개의 댓글

관련 채용 정보