2차 프로젝트 회고

^_^·2022년 9월 15일
0

마이허니트립 프로젝트

마이허니트립

마이허니트립은 마이리얼트립을 모티브로 허니문 항공권 예약과 관련된 사용자의 소셜 로그인(kakao)과 검색결과 기반 상세페이지, 항공권 예약, 마이페이지까지 이어지는 커머스 사이트의 기본적인 Flow 기능을 구현한 사이트이다.

짧은 기간 진행하는 프로젝트이기 때문에 허니문 여행전문이라는 컨셉으로 기획을 잡고 허니문 여행지 4곳의 항공권을 예약하는 사이트를 구현했다.

마이허니트립 (프로젝트 배포 링크)

개발 기간

2022.08.01 ~ 2022.08.12 (12일)

개발 인원

프론트 4, 백엔드 3 (각 git repo)

모델링

내가 구현한 부분

  • csv -> mysql 데이터 입력
  • 비행 예약
    탑승객 별 비행기 예약 시스템 API구현
  • 내 예약
    내가 예약한 비행편 조회 및 취소 API구현
    예약 상세 정보 조회 API구현

처음 사용해본 기능들

transaction

트랜잭션 내의 작업은 모든 작업이 정상적으로 완료되면 데이터베이스에 반영(commit)하거나, 일부 작업이 실패한다면 실행 전으로 되돌리는(rollback) 기능이다. 유저가 예약화면에서 중간에 나가면 데이터베이스에 반영이 되지 않게 하기위해 사용했다.


class BookingView(View):
    @check_access
    def post(self, request):
        try:
            with transaction.atomic():
                data = json.loads(request.body)
                user = request.user
         
 ..............................코드생략..........................
               
            return JsonResponse({'message' : 'SUCCESS'}, status = 200)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)
        except FlightDetail.DoesNotExist:
            return JsonResponse({'message' : 'FLIGHT_DETAIL KEY_ERROR'}, status = 404)

enumfield

아래와 같이 데이터를 지정해놨고 각 예약마다 아이디 값으로 예약 데이터를 불러와야 했다. 처음엔 pk값으로 해당 아이디의 데이터를 불러오고자 했으나 내가 아닌 다른 사람들은 pk값으로 어떤 데이터인지 알아보기 어렵기 때문에 enumfield를 사용해 알아볼 수 있도록 수정했다.

+----+------------------+
| id | name             |
+----+------------------+
|  1 | An upcoming trip |
|  2 | Last trip        |
|  3 | Canceled trip    |
+----+------------------+

class BookingView(View):
    @check_access
    def post(self, request):
        try:
            with transaction.atomic():
                data = json.loads(request.body)
                user = request.user

                passengers     = data['passengers']
                flight_details = data['flight_detail_id']

                upcoming       = BookingStatusEnum.UPCOMING.value
                ticket_confirm = TicketStatusEnum.CONFIRM.value
         
 ..............................코드생략..........................
               
            return JsonResponse({'message' : 'SUCCESS'}, status = 200)
        except KeyError:
            return JsonResponse({'message' : 'KEY_ERROR'}, status = 400)
        except FlightDetail.DoesNotExist:
            return JsonResponse({'message' : 'FLIGHT_DETAIL KEY_ERROR'}, status = 404)

core.py에 enumclass를 작성하고 import 해서 사용했다.

# core.py

class BookingStatusEnum(Enum): 
    UPCOMING = 1
    LAST     = 2
    CANCELED = 3


class TicketStatusEnum(Enum): 
    CONFIRM  = 1
    CANCELED = 2 

annotate

내 여행 페이지 화면이다. 왕복 여행예약시 같은 예약 번호로 가는편 오는편 일정이 편도처럼 따로 표시되고 각각 날짜에 따라 정렬된다.

왕복을 예약했을 경우 갈때와 올때 두비행편을 모두 가져와야 하고 편도면 하나만 가져와야했다. 처음엔 예약 아이디로 승객에 접근하고 해당 예약의 승객 한명의 티켓에 접근해 해당 정보를 가져오는 코드로 작성했다.

for booking in bookings:
    for ticket in booking.passenger_set[0].ticket_set.all():
        ...

문제는 정보는 어떻게든 불러왔는데 이 정보를 비행날짜 별로 정렬 할 수 없었다. 그리고 리스트 슬라이싱으로 불러오니 뭔가 멋도없고 좋은 코드가 아닌거같아 모델링을 수정할지 다른 방법을 찾아야 할지 고민하다 기존 프론트팀원들과 맞춰놓은 부분이 있어 수정하기엔 시간이 충분하지 않다고 판단되어 모델링 수정은 피하기로 했다. 실제 프로젝트 였다면 모델링을 수정 했을거 같다.

예약 정보에 날짜정보까지 있어야 날짜를 기준으로 정렬이 가능하고 왕복예약의 경우 갈때와 올떄를 분리해 표현해야 하기 때문에 annotate를 사용해 해당 booking테이블이 갖고있는 ticket의 출발 날짜를 min_departure_time, max_departure_time으로 붙여줬다.

class MyBookingListView(View):
    @check_access
    def get(self, request):
        try:
            user       = request.user
            status_id  = request.GET.get('status', 'upcoming')

            status_set = {
                'upcoming' : BookingStatusEnum.UPCOMING.value,
                'last'     : BookingStatusEnum.LAST.value,
                'canceled' : BookingStatusEnum.CANCELED.value,
            }

            status_id = status_id if status_id in status_set.keys() else 'upcoming'

            bookings = Booking.objects.select_related('booking_status')\
                .annotate(min_departure_time=Min('ticket__flight_detail__departure_time'), max_departure_time=Max('ticket__flight_detail__departure_time'))\
                .filter(user = user, booking_status_id = status_set.get(status_id))
                
            

왕복의 경우 예약 정보를 복제해 출발 날짜를 기준으로 예약을 두개로 만들었다. 예약을 하나씩 리스트에 추가하면서 왕복인지 확인하고 왕복이면 같은 예약에 다른 시간을 리스트에 담았다.

booking_list = []

for booking in bookings:
    booking_list.append(booking)
    if booking.min_departure_time != booking.max_departure_time:
        booking_return                    = bookings.annotate(min_departure_time=Min('ticket__flight_detail__departure_time'), max_departure_time=Max('ticket__flight_detail__departure_time')).get(id = booking.id)
        booking_return.min_departure_time = booking_return.max_departure_time
        booking_list.append(booking_return)

bookings.annotate(min_departure_time=Min('ticketflight_detaildeparture_time')와 같이 annotate를 사용해 다른 테이블에 접근할 수 있었다. annotate에 대해서는 다시 공부해 따로 포스팅 해야겠다.

회고

좋았던점

새로운 기능을 사용해 좀더 배울 수 있는 프로젝트였다. 테스트 코드도 작성해 봤고(상당히 어려웠지만) 1차 프로젝트에서 해보지 못한 부분을 2차때 해본것도 좋았다. 1차 프로젝트는 모델링이 상대적으로 간단했다(그때는 전혀 간단하지 않았다). 2차에선 클라이언트에게 전달해야할 정보가 많아져 코드를 작성하면서 어떻게 어디에 접근해 정보를 가져와야하는지에 대한 생각을 많이 했던것 같다. 이런 과정에서 팀원들과 의견을 나누고 멘토님에게 더 좋은 방법을 물어보는 과정 자체가 같이 좋은 결과를 찾는 과정같아 즐기면서 했던것 같다.

아쉬운점

초기기획의 중요성을 알게 되었다. 시간이 부족해 테이블의 관계를 더 꼼꼼히 확인 했으면 좋았을것 같다. 테이블을 모두 연결해 놓아서 이렇게 저렇게 가져오면 된다고 생각했던 부분들이 이후 프로젝트 진행에서 발목을 잡았다. 위에서 보았듯...
결국 난 처음 작성한 코드의 대부분을 수정했고 아마 멘토님의 도움이 없었다면 정말 어려웠을 거라는 생각이 든다.

팀원들의 코드를 자세히 알아보지 못했다. 프로젝트 기간동안 코드를 수정하는 시간이 길어지면서 다른 팀원들의 코드에대해 공부하지 못했다. 다른 사람의 코드를 보고 이 사람이 왜 이렇게 코드를 작성했는지 의견을 나누는게 도움이 많이 된다는걸 위코드에서 느꼈다. 이후 시간이 된다면 팀원들과 코드 리팩토링을 하며 서로의 코드에 대해 이야기 해보고싶다.

0개의 댓글