프로젝트 weMakers

Nam Eun-Ji·2020년 11월 27일
0
post-custom-banner

clone site : kakao makers
Github : 바로가기

프로젝트 소개

카카오메이커스는 일반 쇼핑몰과 유사하지만 주문기간 내 최소 수량이 충족되지 않으면 생산을 시작하지 못해 재고를 남기지 않는 펀딩사이트와 유사했다. 쇼핑몰이라는 가장 일반적이면서 보편적인 기능들을 갖추고 있어 처음 시작하는 우리에게 적절한 사이트임이 분명했다. 하지만 2주라는 기간이 정해져있어 할 수 있는 각자의 역량을 파악해 몇개의 기능만을 추려내야 했다.

팀원 구성
백엔드 1명 + 프론트엔드 3명



나의 역할

  • ERD(Entity Relationship Diagram)
    프로젝트를 막 시작했을 때 관계형데이터베이스를 충분히 이해하지 못하고 들어가 다대다 관계일 때 중간테이블을 사용한다는 구조를 이해하지 못하여 어려움이 있었으나, 멘토님들과 동기들 덕분에 관계형데이터베이스의 구조를 이해하고 ERD를 짤 수 있었다.

  • 카카오 메이커스 크롤링(db 구축)
    크롤링 세션에서는 한 페이지내 모든 데이터가 존재했을 때 beautiful soup, requests 로 가져오는 것을 배웠었다. 하지만 카카오메이커스는 상품의 정보를 가져와야했기 때문에 일일이 해당 상품 상세페이지를 들어가서 html 정보를 가져와야만 했다. 때문에 사용하게 된 selenium. 처음 사용하기 때문에 selenium을 이해하기 위해 생각보다 많은 시간을 썼었지만 그로 인해 동적수집의 전체적인 흐름을 이해할 수 있었다. 또한 crawling→csv→db로 이어지는 과정과 crawling→db로 바로 저장하는 방법을 둘 다 해보았을 때 csv로 저장 후 db에 저장하는 방법이 과정이 좀 더 늘어났음에도 불구하고 잘못들어간 db를 삭제할 경우는 확실히 줄어준다는 점을 배웠다.

  • 회원가입 API
    비밀번호 내에 문자와 숫자, 특수문자 등을 필수로 1개씩 넣게 한다거나, 이메일형식을 꼭 갖춰야만 저장될 수 있게 하는 등 이런 부분들이 프론트엔드에서 제약을 두고 넘어온 데이터를 바로 db에 저장할 줄 알았는데 만약의 경우를 위해 백에서도 대비해야한다는 점들이 흥미로웠고, 정규표현식과 장고에서 제공하는 validate_email메소드를 이용해 다양한 exception에 대해 대처하였다.

  • 인증 / 인가 API
    인증에서는 회원가입시 검증했던 절차를 똑같이 거쳐 실수로 들어오는 데이터에 대한 검증을 한 번 더 할 수 있게 짰다. 인가에서는 데코레이터를 이용해 유저의 정보가 필요한 로직에 인가절차를 거쳐 해당 유저의 정보를 넘겨주게 하였다.

  • home API / 상품상세페이지 API
    실제로 db에 저장된 상품 데이터들을 가져오는 로직을 짰다. home api에서는 한번에 모든 데이터들을 가져오다보니 프론트에서 약간의 딜레이가 보였다. 하지만 이미 프론트엔드 담당자는 데이터 형식을 지정해놓고 개발이 들어가 바꾸기 힘들어서 그대로 보내준 점이 아쉬웠었고, 객체의 키를 db에 저장되어있는 컬럼명과 통일시키면 편할 것 같은데, 미리 전달하지 못한 점에 대해 매우 아쉬웠다. 이 부분에서 팀원들과의 소통이 얼마나 중요한지에 대해 깨닫게 되었고 api문서화를 하면 이번 프로젝트를 겪은 문제점들이 많이 해소되지 않을까 생각되었다.



잘했던 점, 아쉬웠던 점, 개선방법

  • 잘했던 점
    관계형데이터베이스의 개념을 명확히 잡고 가서 모델링을 하는데 크게 어려움 없이 구현하였다. 또한 처음해보는 동적수집 크롤링에 대한 이해를 충분히 하고 간 것 같아 다음번 프로젝트에서 크게 어려움 없이 진행할 것 같다.

  • 아쉬웠던 점
    나의 역량을 충분히 이해하지 못하고 시작했던 점이 아쉬웠다. 구현하고 싶었던 기능들은 많았으나 쿼리셋과 크롤링에 대한 지식 부족으로 인해 시간 분배를 제대로 하지 못했다. 또한 프론트엔드 팀원들과 api에 대한 소통이 원활하지 못했던 점이 가장 큰 아쉬움으로 남는다.

  • 개선방법
    api 문서화를 통해 전달되는 데이터가 어떤 형식, 어떤 key로 전달되어야하는지 사전 협의가 필요할 것 같다. 또한 mysql에서 join하는 것과 django에서 join하는 문법이 다르기 때문에 충분히 공부하고 넘어가야할 것 같다.



기록하고 싶은 코드, 로직

  • 로그인 데코레이터
import jwt
import json

from django.http       import JsonResponse
from wemakers.settings import SECRET_KEY 
from .models           import Users

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            auth_token = request.headers.get('Authorization')
            payload = jwt.decode(auth_token, SECRET_KEY, algorithm='HS256')
            user = Users.objects.get(id=payload["id"])
            request.user = user
            return func(self, request, *args, **kwargs)
        except Users.DoesNotExist:
            return JsonResponse({'message':'INVALID_USER'}, status = 400)
        except TypeError:
            return JsonResponse({'message':'INVALID_VALUE'}, status = 400)
        except KeyError:
            return JsonResponse({'message': 'INVALID'}, status = 400)
        
    return wrapper
  • 상세페이지 get view
class DetailView(View):
    def get(self, request, product_id):
        product = Products.objects.prefetch_related('productsubimages_set').select_related('main_category','sub_category').get(id=product_id)
        result = {
            'id'              : product.id,
            'name'            : product.name, 
            'price'           : int(product.price),
            'delivery_charge' : int(product.delivery_charge),
            'delivery_date'   : product.delivery_date.strftime("%Y-%m-%d"),
            'end_date'        : (product.end_date.date() - datetime.now().date()).days,
            'minimum_count'   : product.minimum_count,
            'maximum_count'   : product.maximum_count,
            'main_category'   : product.main_category.name,
            'sub_category'    : product.sub_category.name,
            'sub_image'       : list(product.productsubimages_set.all().values_list('sub_image', flat=True))
        }

        return JsonResponse(result, safe=False, status=200)
profile
한 줄 소개가 자연스러워지는 그날까지
post-custom-banner

0개의 댓글