1차 프로젝트

박경철·2021년 6월 13일
0

Project

목록 보기
1/2

1. 프로젝트 소개

맛있는 간편식. 밀캣이 만든 신박한 간편식과 디저트 제품을 한 눈에! '쿠켓 마켓'(https://cookatmarket.com/ko) 웹사이트 클론.
프로젝트 기간: 2021년 06월 07일 ~ 2021년 06월 18일
프로젝트 참가자 (Front & Back)
🔜 FrontEnd: 강준희, 박준우
🔙 BackEnd: 김성규, 김혜지, 박경철

2. 구현 범위 설정

2.1 필수 구현

  • 회원가입
  • 로그인
  • 상품 리스트
  • 상품 상세

2.2 추가 구현

  • 관심 상품
  • 장바구니
  • 검색

3. 모델링

4. 기능구현

4.1 상품 상세 기능

각 상품의 대한 정보(필수 옵션, 선택 옵션 등..) 및 추천 상품의 데이터를 제공, 해당 Food 한개의 정보만 확인하기 때문에 RESTful Path Parameter 방식으로 선택된 Food_id로 Food 정보를 확인.

class FoodView(View):
    def get(self, request, food_id):
        try:
            food             = Food.objects.get(id=food_id)
            recomanded_foods = Food.objects.filter(
                categoryfood__category_id=food.categoryfood_set.first().id
            )
            
            required_option = [{
                    'id'      : required_option.id,
                    'food_id' : food.id,
                    'name'    : required_option.name,
                    'price'   : required_option.price
                }for required_option in food.requiredoption_set.all()]

            select_option = [{
                    'id'      : select_option.id,
                    'food_id' : food.id,
                    'name'    : select_option.name,
                    'price'   : select_option.price,
                }for select_option in food.selectoption_set.all()]
            
            result = {
                'name'             : food.name,
                'price'            : food.price,
                'discount'         : food.discount,
                'discounted_price' : food.discounted_price,
                'star_score'       : food.star_score,
                'review_count'     : food.review_count,
                'detail_image'     : food.detail_image,
                'create_at'        : food.create_at,
                'update_at'        : food.update_at,
                'image'            : [image.image_url for image in food.foodimage_set.all()],
                'required_food'    : required_option,
                'select_food'      : select_option,
                'recommend_food'   : [{
                    'name'  : food.name,
                    'price' : food.price,
                    'image' : food.foodimage_set.filter(food=food).first().image_url
                } for food in recomanded_foods],
            }

            return JsonResponse({'message':result}, status=200)

        except Food.DoesNotExist:
            return JsonResponse({'message':'NOT EXIST'}, status=404)

        except MultipleObjectsReturned:
            return JsonResponse({'message':'MULITIPLE FOODS'}, status=400) 

로그인 상태 일 경우 해당 Food가 관심 상품에 등록되어 있는지 확인하는 기능, RESTful Path Parameter 방식으로 사용.

class WishFoodView(View):
    @login_decorator
    def get(self, request, food_id):
        is_wised = Wish.objects.filter(user=request.users, food_id=food_id).exists()

        return JsonResponse({'wish_status' : is_wised}, status=200)

4.2 관심 상품 기능

관심 상품 등록, 제거, 보기 기능은 로그인 상태에 있을 경우만 가능하기 때문에 Login 상태 확인을 위해 Login Decorator를 추가.
Header에서 Authorization Token 데이터를 JWT를 사용하여 User 정보를 가져옴.

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            acess_token    = request.headers.get('Authorization', None)
            amount            = jwt.decode(acess_token,SECRET_KEY,ALGORITHM)
            users                = User.objects.get(id=amount['id'])
            request.users  = users
        except jwt.DecodeError:
            return JsonResponse({'message' :'INVALID_TOKEN'}, status=400)
        except User.DoesNotExist:
            return JsonResponse({'message' : 'INVALID_USER'}, status=400)
        return func(self, request, *args, **kwargs)
    return wrapper

로그인 상태 확인 후
해당 User가 관심 상품 등록을 위해 Post,
관심 상품에 등록된 Food를 제거하기 위해 Delete,
User가 등록한 모든 관심 상품을 가져오기 위해 Get 기능을 구현.

class WishView(View):
    @login_decorator
    def post(self, request):
        try:
            data = json.loads(request.body)

            if Wish.objects.filter(user=request.users, food_id=data['food_id']).exists():
                return JsonResponse({'message':'DUPLICATED_FOOD'}, status=400)

            wish = Wish(user=request.users,food_id=data['food_id'])
            wish.save()
        
            return JsonResponse({'message':'SUCCESS'}, status=201)
        
        except IntegrityError:
            return JsonResponse({'message':'FOOD INVALID'}, status=400)
    
    @login_decorator
    def delete(self, request, food_id):
        try:
            wish = Wish.objects.get(user=request.users, food_id=food_id)
            wish.delete()
        
            return JsonResponse({'message':'NOT_CONTENT'}, status=204)
        
        except Wish.DoesNotExist:
           return JsonResponse({'message':'NOT EXIST'}, status=404)

    @login_decorator
    def get(self, request):
        wishes = Wish.objects.filter(user = request.users)
        
        result  = ([{
            'name'             : wish.food.name,
            'price'            : wish.food.price,
            'discount'         : wish.food.discount,
            'discounted_price' : wish.food.discounted_price,
            'star_score'       : wish.food.star_score,
            'review_count'     : wish.food.review_count,
            'detail_image'     : wish.food.detail_image,
            'create_at'        : wish.food.create_at,
            'update_at'        : wish.food.update_at,
            'image'            : wish.food.foodimage_set.filter(food=wish.food).first().image_url
        } for wish in wishes] if wishes else [])

        return JsonResponse({'wish_list':result}, status = 200)

5. 협업 도구

  • Trello
  • Git
  • GitHub
  • Slack

6. 구현 영상

7. 회고록

  • 데이터베이스 모델링의 중요성
  • 협업 및 소통
  • 리펙토링

참고

프로젝트 자료 링크

profile
안녕하세요!

0개의 댓글