[위코드 1차 프로젝트] 오늘의집 클론코딩 (기능관련)

여주링·2020년 12월 27일
3

Project

목록 보기
5/6
post-thumbnail

🏠위코드 15기 폭주기관차🚄팀

  • 진행기간: 2020년 12월 14일 ~ 2020년 12월 24일

전반적인 프로젝트 감상은 여기👈 클릭~

프로젝트 소개

'늘집'시연 영상

-FrontEnd

  • HTML / CSS / JavaScript (ES6) / React (CRA 세팅) / Sass

-BackEnd

  • Python / Django / CORS Header / Bcrypt / PyJWT / MySQL / AqeuryTool (데이터베이스 모델링)

-협업 도구

  • Slack / Git + GitHub / Trello를 이용, 일정관리 및 작업 현황 확인 / Postman (API 관리)

-내가 담당한 부분

1)회원가입 & 로그인

  • bcrypt를 사용한 암호화
  • JWT 로그인 구현 및 @decorator를 이용해서 토큰 인증
  • Email&닉네임 정규화를 통한 Validation적용

2)장바구니

  • 상품의 장바구니 등록 (개수 포함)
  • 장바구니 내역 조회
  • 장바구니 상품 수량 변경 및 가격반영(DB에 전부 반영되도록 설정)

구현기능을 통해 배운점

1. 모델링 구축

<처음 시작>

<최종안>
이번에 프로젝트에서 제일 고생을 많이했다. 처음에 장바구니등등 몇가지 기능을 제외하고 모델링을 구축했는데, 중간에 table의 column이 변경되고, 장바구니를 넣기로 결정하면서 계속 변동이 되었다.
그리고 사용하지 않는 테이블과 column값이 생겨나며 해당부분,연결부분을 공백처리하는것 까지 심도있게 생각하느라 진이 빠졌다😞
but, 이부분을 부정적으로 생각하지는 않는다.
생각해보면 오히려 1차에서 신중한 모델링의 중요성을 알게되어 다행이라고 생각될 정도! 이렇게 모델링을 직접 구축하고 수정하는 과정을 기업에서 할 수 있을까? 누구나 할순 없다고 생각된다. 1차에서의 경험으로 2차에서 더 좋은 모델링을 할 수 있을거라고 생각한다.

2. 회원가입&로그인 - 데코레이터를 만나다

  • 데코레이터에 대한 개념 이해
  • 데코레이터을 실제 웹페이지에 적용
#user.modles.py와 동일한 user앱에서 utils.py생성후 작성
import jwt
from django.http import JsonResponse
from my_settings import SECRET, ALGORITHM
from user.models import User

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        if "Authorization" is None:
            return JsonResponse({"MESSAGE":"INVALID_LOGIN"}, status=401)
        encode_token = request.headers["Authorization"]
        try:
            data         = jwt.decode(encode_token, SECRET, ALGORITHM)
            user         = User.objects.get(id = data["id"])
            request.user = user        
        except jwt.DecodeError:
            return JsonResponse({"MESSAGE" : "INVALID_TOKEN"}, status = 401)
        except User.DoesNotExist:
            return JsonResponse({"MESSAGE" : "INVALID_USER"}, status = 401) 
        except jwt.InvalidTokenError:
            return JsonResponse({'MESSAGE': 'INVALID_ACCESS_TOKEN'}, status=401)       
        return func(self, request, *args, **kwargs)
    return wrapper

상당히 많은 컴퓨터 지식이 들어가는 로직이라 생각한다. .gitignore,암호화,유효성검사뿐만아니라 HTTPrequest/response의 개념도 숙지한상황에서야 이 로직을 작성할 수 있었다.
지금까지는 HTTP,Django,python이 다 따로사용되는거라고 생각했었는데, 이게 한 곳에서 함께 사용되는거에 혼란을 느꼈다. 회원가입,로그인은 위스타그램에서 배운 개념 그대로 적용하는 거라 복습하는 기분으로 쉽게 접근했지만, 데코레이터는 다른분들이 작성한 로직을 이해하는데 많은 시간을 보냈다.
많이 고생했는데, 로그인 이후 사용자 확인이 필요한 상황에서 절묘하게 잘 쓰여서 뿌듯한 로직중에 하나이다
(에러관련해서 조금 추가하고 싶다는 생각이 드니 나중에 꼭 수정하자)

3. 장바구니에 상품 추가

데코레이터를 이용해 특정유저에가 원하는 상품을 유저의 장바구니에 추가하는 로직을 작성했다. post를 로그인,회원가입 이외의 화면에서 처음 구현해보았는데 역시 반복학습을 해서 그런지 적용하는데는 큰 문제가 없었다.

class CartView(View):
    #장바구니 등록
    @login_decorator
    def post(self, request):
        data = json.loads(request.body)
        user = request.user
        try:   
            if Cart.objects.filter(
                user=user.id, 
                product=data['product_id'], 
                color=data['color_id']).exists():
                item = Cart.objects.get(
                    user=user.id, 
                    product=data['product_id'], 
                    color=data['color_id'],
                    option=data['option_id'])
                item.quantity += int(data['quantity'])
                item.save()
                return JsonResponse({"message":"SUCCESS"}, status=200)      
            Cart.objects.create(
                user     = User(id = user.id),
                product  = Product(id = data['product_id']),
                quantity = int(data['quantity']),
                color    = OptionColor(id = data['color_id']),
                option    = Option(id = data['option_id'])
            )
            return JsonResponse({"message":"SUCCESS"}, status=201)
        
        except KeyError as ex:
            return JsonResponse({"message":"KEY_ERROR_" + str(ex.args[0])}, status=400)

3. patch개념에 익숙해짐

장바구니를 구현할 예정이 없었는데, 급하게 진행하게 되었다.

patch라는 개념을 이번프로젝트를 진행하며 처음 보았는데, 주변 동기분들중에 생각보다 적용하신분들이 적어서 좀 뿌듯한 코드중에 하나이다.
http 매서드중 update에서 사용되는 개념으로 put도 존재하지만 장바구니의 특성상 수량만 변경이 되는거라 일부를 수정하는 patch를 적용했다.

class CartDetailView(View):
    @login_decorator
    def patch(self, request, cart_id):
        try: 
            data = json.loads(request.body)
            item = Cart.objects.get(id = cart_id)
            item.quantity = int(data['counts'])
            item.save()
            
            return JsonResponse({
                "message"  : "SUCCESS", 
                "QUANTITY" : item.quantity, 
                "PRICE"    : item.option.price * int(item.quantity)}, status=201)

        except KeyError as ex:
            return JsonResponse({'message' : 'KEY_ERROR_' + ex.args[0]}, status=400)

처음에는

def patch(self, request):

만 적용했었는데 수량변경시 변경된 수량이 적용되는게아닌, 중복에러가 발생하는것을 확인하고 멘토님께 조언을 받아 cart_id를 추가했다.

4.프론트와의 협업

프론트와의 통신에 있어서 API의 중요성와 키워드를 잘 정해주는거에 대한 중요성을 깨달았다.
같은 user라도 프론트에서 User라고 키워드를 넣는 순간, 둘은 다른 변수가 되므로 에러가 일어난다. 이부분을 정확히 숙지하고 사전에 백,프론트에서 이 부분을 잘 협의해야한다는걸 알았다.
이번 1차 프로젝트의 경우 프론트분들이 알아서 내가 원하는걸 잘 받아주셨는데, 이게 엄청난 지식에서 나온다는것을 다른 프론트분들을 통해서 알고 놀랐다.
2차에서는 좀더 잘 소통을 해서 문제없이 통신이 되도록 노력해야겠다는 생각이 들었고, 지금은 백엔드적인 지식만 있지만 꼭 프론트적인 지식도 공부를 해야겠다는 생각이 들었다.

profile
🌱Backend Developer👩‍💻

0개의 댓글