두번째 프로젝트 | 야,여기어때

신지원·2021년 5월 16일
1
post-thumbnail
post-custom-banner


여기어때 홈페이지를 모티프로하여 진행한 프로젝트입니다.

  • 개발인원
    총 6인 (프론트-3인, 백엔드-3인)

  • 개발기간
    2021/4/26 ~ 2021/5/7 (2주)

  • GitHub
    프론트엔드
    백엔드

  • 협업툴
    Slack
    Trello
    Git


💡 직접 구현한 기능

  • 소셜 로그인(카카오)
  • 호텔 예약하기: 호텔 예약하면 status를 예약 완료 상태로 변경하고, 날짜별 예약 확인 테이블에서 남은 호텔 갯수를 1씩 줄여주기
  • 예약한 호텔 리스트 데이터 전달: 예약 완료된 호텔들, 취소된 호텔들의 정보를 전달
  • 예약 취소하기: 호텔 예약을 취소하면 status를 예약 취소로 변경하고, 날짜별 예약 확인 테이블에서 남은 호텔 갯수를 1씩 더해주기

⭐️ 기억하고 싶은 코드

카카오 소셜 로그인 기능

class kakaoView(View):
   def post(self, request):
       try:
           access_token = request.headers.get('Authorization', None)
           url          = 'https://kapi.kakao.com/v2/user/me'
           headers      = {'Authorization': f'Bearer {access_token}',
                           'Content-type': 'application/x-www-form-urlencoded;charset=utf-8'
           }

           response      = requests.get(url,headers=headers)
           data          = response.json()
           kakao_user_id = data['id']
           email         = data['kakao_account']['email']
           nickname      = data['kakao_account']['profile']['nickname']

           if not User.objects.filter(kakao_user_id=kakao_user_id).exists():
               User.objects.create(
                   kakao_user_id = kakao_user_id,
                   email         = email,
                   nickname      = nickname,
                   is_social     = True
               )

           token = jwt.encode({'id': User.objects.get(kakao_user_id=kakao_user_id).id}, my_settings.SECRET['secret'], algorithm=my_settings.ALGORITHM)
           return JsonResponse({'TOKEN': token, 'NICKNAME': nickname},status=200)

       except KeyError:
           return JsonResponse({'MESSAGE': 'KEY_ERROR'},status=401)
  • 처음으로 외부 api를 이용해서 구현한 카카오 소셜 로그인 기능
    프론트에게 토큰을 받고, 그것을 다시 카카오 측으로 보내면 카카오가 그 토큰에 맞는 해당 user의 정보를 json 형태로 보내준다. 그리고 나서 내가 원하는 것만 뽑아내고, 우리의 홈페이지에서 쓸 token을 발급한다.
    공식 문서만을 보고 이해하려고 노력했던 부분이라서 아직까지 기억에 남는다...!

예약하기 기능

  • transaction.atomic()
    트랜잭션에 대해서 처음 알게 되었다.

유닛 테스트를 하던중 transaction 오류가 떠서 처음 찾아보게 되었다.

transaction은 하나의 수정작업이 실패하면 트랜젝션 상의 모든 업데이트가 실패전으로 돌아온다.
이번의 경우에는, 호텔을 예약하면 호텔들의 남은 방의 갯수를 건들여주어야 하는 작업이 필요했기 때문에 필요한 일이었다.

class ReservationView(View):
    @LoginDecorator
    def post(self,request):
        try:
            data = json.loads(request.body)
            user = request.user

            RESERVED = 1

            name         = data['name']
            phone_number = data['phone_number']
            check_in     = data['check_in']
            check_out    = data['check_out']
            status       = Status.objects.get(id=RESERVED)
            hotel        = Hotel.objects.get(name=data['hotel'])
            room         = Room.objects.get(name=data['room'], hotel__name=data['hotel'])

            if not name or not phone_number:
                return JsonResponse({'MESSAGE':'NO_INFORMATION'},status=404)

            with transaction.atomic():
                Reservation.objects.create (
                    name         = name,
                    phone_number = phone_number,
                    check_in     = check_in,
                    check_out    = check_out,
                    status       = status,
                    user         = user,
                    hotel        = hotel,
                    room         = room,
                )

            check_in_date  = datetime.datetime.strptime(check_in, '%Y-%m-%d')
            check_out_date = datetime.datetime.strptime(check_out, '%Y-%m-%d')
            days           = (check_out_date - check_in_date).days

            REMAIN = 0

            for use_day in range(days):
                reservation_remain = ReservationCheck.objects.get(room=room, date=check_in_date)
                if reservation_remain.remain == REMAIN:
                    return JsonResponse({"MESSAGE": "NO_REMAIN_ROOM"},status=404)
                else:
                    reservation_remain.remain -= 1
                    reservation_remain.save()
                    check_in_date = check_in_date + datetime.timedelta(days=1)

            return JsonResponse({'MESSAGE':'SUCCESS'}, status=200)

        except KeyError:
            return JsonResponse({'MESSAGE':'KEY_ERROR'},status=400)

        except ValidationError:
            return JsonResponse({'MESSAGE':'VALIDATION_ERROR'}, status=404)

        except Hotel.DoesNotExist:
            return JsonResponse({'MESSAGE':'NO_HOTEL'}, status=404)

        except Room.DoesNotExist:
            return JsonResponse({'MESSAGE':'NO_ROOM'}, status=404)

남은 방의 갯수를 계산해주는 부분을 꼭 리펙토링 하고싶다!

프로젝트 후기

이번 프로젝트를 통해서 개인적으로 잘했다고 생각한 점은 구글링하기와 공식 문서 참고!!

1차때는 구글링을 해도 뭘 봐야될지 막막하니깐 꼼꼼히 보기 힘들었는데, 이번에는 하나씩 꼼꼼하게 살펴보기 위해 많이 노력했던것 같다. 그랬더니 확실히 1차보다 혼자 해결 할 수 있는 부분이 늘어났다.

1차때는 협업의 중요성을 깨닫고 다른 사람들과 같이 협업하는 시간의 중요성을 배웠다면, 이번 2차 프로젝트를 통해서는 스스로 코드를 짜기 위해 혼자서 고민하는 시간들의 소중함을 배웠던것같다. 그러다 보니 지금 당장은 어떻게 하는건지 몰라서 헤맬 수 있지만 시간이 지나면 결국 해낼 수 있을것이라는 자신감이 조금은 생겼다.
프로젝트 진행 하면서 겁부터 먹어서 추가 기능으로 빼버린것도 있었는데, 결국 그 부분까지 해냈다. 지레 겁부터 먹는 점도 내가 버려할 습관 중에 하나인 것을 깨닫게 된 시간이었다.

post-custom-banner

0개의 댓글