>Wecode 1차 프로젝트 회고

Jayson Hwang·2022년 6월 5일
3

“My code DOESN’T work, I have no idea why. My code WORKS, I have no idea why.”

위 말처럼 우스갯소리로 하는 말이지만, 내가 밟아온 과정들을 다시 소중히 정리하지 않는다면 온전히 내 것으로 만들지 못할 것만 같다.

내가 심여를 기울여 작성한 코드들, 그리고 그런 코드들을 더 알맞고 효율적인 형태로 가꾸는 방법을 나에게 알려주기 위해 노력한 여러 사람들의 가르침을 헛되이 하고싶지 않기에 내가 경험한 배움의 과정들을 이 곳에 남겨보려한다.


0.. Overview

클론 사이트 : 오설록 (https://www.osulloc.com/kr/ko)

개발 기간 : 2022.05.23 ~ 2022.06.03 (2주)

프로젝트 소개 :

  • 학습 목적으로 제작한 '오설록' 사이트 클론 프로젝트

  • 커머스 사이트의 가장 기본적인 기능 구현

  • Wesulloc 시연 영상


1.. Team Wesulloc

팀명 : 위설록 (Wesulloc)

Member :

  • Front-End : 이윤섭(PM)님, 손가영님, 김현주님, 안수정님

  • Back-End : 황재승, 최바다님


2.. Tech Stacks

- Back-End

  • Python, Django, MySQL, CORS Header, Bcrypt, PyJWT
  • AWS EC2, AWS RDS

- API DOCUMENTATION

3.. Communication Tools

  • SLACK & TRELLO 을 활용한 프로젝트 일정 관리 및 진행 현황 공유

4.. Goals

  • 커머스 웹사이트의 가장 기본적이고 필수적인 기능을 완성하기

  • 프론트엔드의 개발 속도에 맞추어 완벽히 데이터를 전달할 수 있도록 진행상황 관리하기

  • 가독성이 높은 코드 작성하기

  • 연산처리 속도에 신경써서 코드 작성하기

  • 어려운 부분을 마주하면 팀원과 소통하여 함께 헤쳐나가기

  • 과한 욕심으로 프로젝트 전체 계획에 차질 주지 않기


5.. Implementation of Functions

5-1.. 모델링

모델링을 할 때, 가장 기준이 되는 테이블을 PRODUCT로 선정하고 차례차례 그림을 그려나갔다. 특히, 중복 카테고리를 가지고 있는 제품들이 있어 관계를 설정하는 데 있어서 많은 고민을 했다.
(ORDER와 관련된 테이블은 모델링 단계에서 미리 구상하였지만, 추가 기능구현 사항으로 일단 배제해두었다.)


5-2.. 초기 데이터 세팅

클론 코딩을 진행할 사이트의 핵심 기능들에 대한 간단한 초기 데이터를 google spreadsheet을 사용해서 구상하였고, 이를 토대로 scv 파일을 따로 작성하여 MySQL WORKBENCH를 통해 DB에 저장하였다.


5-3.. 메인페이지

  • 상품 리스트 호출 (ProductListView - GET)


5-3.. 회원가입 & 로그인

함께 프로젝트 진행하신 바다님께서 맡아주신 부분!

  • bcrypt를 이용한 비밀번호 암호화(encode, decode)
  • 로그인 시 JWT 토큰 발급
  • Login Decorator를 통한 인가 확인 기능


5-4.. 상품 리스트, 상품 상세 페이지

  • 전체 카테고리의 상품 리스트 구현
  • 카테고리 별 상품 리스트 구현
  • Annotate를 통한 필터 기능 구현
  • Pagination 구현
  • Q 객체와 Query Parameter 이용
  • prefetch_related()를 통한 연산처리 개선
  • 상세페이지 내 할인

5-5.. 장바구니 (CRUD)

  • 상품 상세 페이지에서 특정 상품을 바로 장바구니에 담을 수 있도록 뷰 작성
  • 이미 장바구니에 있는 물품을 다시 장바구니에 담을 경우, 해당 제품의 수량만 증가할 수 있도록 코드 작성
  • 장바구니에 담긴 특정 상품의 수량 변경 (CartView - PATCH)
  • 장바구니에 담긴 특정 상품 삭제 (CartView - DELETE)

5-6.. 리뷰 (GET, POST, DELETE)

  • 리뷰 작성 (ReviewView - POST)
  • 리뷰 리스트 (별점, 평균 별점, 총 리뷰수) (ReviewView - GET)
  • 작성한 리뷰 삭제 (ReviewView - DELETE)

6.. 기억에 남는 코드

::: 하나의 Method를 통해 DB에 액세스하는 횟수를 줄여주어 Performance를 크게 향상시킴

< BEFORE >

class CategoryView(View):
    def get(self, reqeust):
        menus = Menu.objects.all()

< AFTER >

class CategoryView(View):
    def get(self, reqeust):
		menus = Menu.objects.all().prefetch_related('maincategory_set', 'maincategory_set__category_set')

6-2.. Q 객체 & Annotate 사용

q = Q(
if menu:
    q &= Q(categoryproduct__category__main_category__menu__id = menu
if main_category:
    q &= Q(categoryproduct__category__main_category__id = main_category
if category:
    q &= Q(categoryproduct__category__id = category
if search:
    q &= Q(name__icontains = search
sort_type = {
    'reviews'   : '-total_reviews',
    'sales'     : '-total_sales',
    'new'       : '-id',
    'price_desc': '-price',
    'price_asc' : 'price'
    
products = Product.objects.filter(q).annotate(total_sales=Sum('orderitem__quantity', distinct=True))\
    .annotate(total_reviews=Count('review__id', distinct=True))\
    .order_by(sort_type.get(sort))[offset:offset+limit]

6-3.. 더 나아간 Dictionary Unpacking!!!

filter_set = {
    'main_category' : 'categoryproduct__category__main_category__id',
    'menu' : 'categoryproduct__category__main_category__menu__id',
    'category' : 'categoryproduct__category__id'
}

filter = {filter_set[key] : value for key, value in request.GET.items()}

products = Product.objects.filter(**filter).annotate(total_sales=Sum('orderitem__quantity', distinct=True))\
            .annotate(total_reviews=Count('review__id', distinct=True))\
            .order_by(sort_type.get(sort))[offset:offset+limit]

7.. Project Review

7-1.. 좋았던 점

  • FE & BE 소통 및 팀의 분위기
    개개인 팀원 모두의 명확한 의사소통과 매일 진행되는 Stand-Up Meeting에서의 각자의 진행상황 공유를 통해서 요청/전달 사항들에 대해서 명확히 할 수 있었다.

  • 코드 리뷰
    오랜 시간동안 고민하고 작성한 코드에 대해서 멘토님께서 명확히 리뷰를 해주셔서 너무 감사했다.
    나 또한 정확한 피드백을 받기위해서 PR을 올릴 때마다 "지금 이 코드를 작성한 이유" 및 "작성 과정에서 갖게된 의문점"에 대해서 항상 명확히 설명하도록 노력했고, 멘토님께서는 이 부분에 대해서 내가 정확히 이해할 수 있도록 항상 짚고 넘어가주셨다.
    지금 생각하면 1차 프로젝트를 진행하는 과정에 있어서 코드를 리뷰받는 그 시간이 가장 재밌고 유익했던 것 같다.

7-2.. 아쉬웠던 점

  • 시간 분배 실패
    계획했던 필수 기능 구현은 성공적으로 마쳤다.
    하지만, 애초에 내가 계획한 것은 ORDER에 대한 부분까지 시간 내에 구현하는 것이었고, 안일한 시간분배로 인해서 결국은 실패하고 말았다. 조금 더 빠듯하게 시간을 분배해서 진행했다면 충분히 추가기능까지 구현 가능했었을 것이다.

  • API 명세서
    모델링 과정부터 프론트엔드 분들과 조금 더 의논하고, 각자 구현하시는 페이지에 필요한 데이터들에 대해서 좀 더 많이 이야기할 수 있는 시간을 갖지 못한 부분이 아쉬움으로 남았다.
    또한, 그 시간의 부재로 인하여 그리고 나의 무지로 인하여 API Documentation 없이 프로젝트를 계속 진행하였고, 결국 통신하는 과정에서 프론트엔드에서 필요한 데이터를 놓쳐 부랴부랴 추가해서 전달해야했던 치명적인 실수까지 하고 말았다.


8.. 2차 프로젝트 때 해야할 것

  • logger로 sql 찍어가면서 db 성능을 더 고려한 코드(ORM) 작성
  • Dictionary Unpacking을 좀 더 자유자재로 사용해보기
  • 명확한 API DOCUMENTATION 작성

9.. 진짜 회고...

위코드에 와서 시간을 보낸 1달 반가량의 기간동안 내가 어렵게 선택한 이 길이 나에게 진짜 맞는 길인지, 위코드에서의 기간이 끝나면 정말로 내가 한 명의 개발자로써 현업에서 일할 수 있을지 계속 고민해왔다.

서로 화이팅 하며 응원해주는 팀원 덕분에 1차 프로젝트를 진행하는 동안은 그런 고민을 단 한번도 하지 않게 되었고(고민할 시간도 없었지만...), 처음으로 함께 맞춰가는 개발이 재밌다고 느꼈다.

그리고, "함께 성장하는 개발자" 가 되고 싶다 생각했다.

분명히 프로젝트를 만족스럽게 마무리할 수 있었던 것은 분명 팀원 모두가 배려하고 노력했기 때문임으로 잘 알고 있다.
나 또한 함께 끌어가고 끌어줄 수 있는 개발자가 되보고자 노력한다.

Many Thanks to Team Wesulloc...

profile
"Your goals, Minus your doubts, Equal your reality"

2개의 댓글

comment-user-thumbnail
2022년 6월 5일

좋은 글 잘 읽고 갑니다~

답글 달기
comment-user-thumbnail
2022년 6월 5일

함께 성장하는 개발자라는 말이 참 좋네요! 재승님 회고 정말 잘 읽고갑니당

답글 달기