예약 API
회고록
이번 프로젝트에서 맡은 담당은 예약 API이다.
예약 API는 이전 장바구니 API와 비슷한 로직으로 구현하면 된다는 생각이 든다.
빠르게 로직을 구현 후 다른 팀원들을 도와주고 싶은데 잘될지는 모르겠다...
이전 장바구니 API로직을 구현 후 리펙토링을 하지 않았는데, 이번 기회에 비슷한 로직을 구현 하면서 좀 더 좋은 코드가 있는지 고민해 볼려고 한다.
추가 회고
프론트와의 커뮤니케이션에 착오가 있었다....
서로 커뮤니케이션이 됬다고 생각했지만, 그게 아니었다.
프론트에서는 예약메인페이지가 있고, 예약 상품을 누르면 상세예약페이지로 넘어가는 페이지를 구현했다.
하지만 커뮤니케이션 당시 내가 잘못 알아들 어 상세예약페이지에 대한 로직을 구현하지 않았다.
남은기간은 하루, 빠르게 로직을 구현했다.
어렵지 않는 로직이었으므로 구현하는데는 문제가 없었으나,
커뮤니케이션이 되지 않아 발생한 문제에 대해서 깊이 생각해 볼 필요가 있었다.
프론트에서 설명하는 부분에 대해서 이해가 부족하다보니 어림짐작으로 이렇구나 하고 넘어간 부분도 있었던 것 같다. 그러다보니 커뮤니케이션이 되지 않았던 것이다.
로직을 구현하는 내가 좀더 적극적으로 프론트와 커뮤니케이션하려고 했어야 하는데 그게 않되었던 것 같다.
이번 처럼 단순한 구현이 아닌, 시간이 걸리는 로직이었다면, 분명 큰 문제가 됬을 것이다....
이전 프로젝트의 회고에서 커뮤니케이션의 중요성을 느꼈고, 회고 당시 개선사항으로 생각했지만, 이번 프로젝트 역시 같은 문제가 발생했다는 점에 반성을 해야한다고 느낀다...
MainReservation GET
class MainResevationsView(View):
@signin_decorator
def get(self, request):
# user = User.objects.get(id = 8)
reservations = Reservation.objects.select_related("room") \
.prefetch_related("room__image_set") \
.filter(user = request.user)
result = [{
'reservation_number' : reservation.number,
'room' : reservation.room.name,
'check_in' : reservation.check_in,
'check_out' : reservation.check_out,
'images' : reservation.room.image_set.all()[0].url,
'address' : reservation.room.address,
'detail_address' : reservation.room.detail_address
} for reservation in reservations]
return JsonResponse({"RESULT": result}, status=200)
select_related()를 활용해서 join을 이용해서 관련된 데이터를 가지고 왓다.
prefetch_related()를 역참조에 해당하는 데이터를 가지고 왔다.
orm 최적화를 이용해서 데이터베이스에 접근하는 것을 최소화하는 로직을 구현했다.
MainReservation POST
@signin_decorator
def post(self, request):
try:
# user = User.objects.get(id = 8)
data = json.loads(request.body)
user = request.user
room = Room.objects.get(id=data['room'])
check_in = data['check_in']
check_out = data['check_out']
people = data['people']
price = data['price']
number = uuid.uuid1()
Reservation.objects.create(
check_in = check_in,
check_out = check_out,
people = people,
room = room,
user = user,
price = price,
number = number
)
return JsonResponse({"MESSAGE": "SUCCESS"}, status=201)
except KeyError:
return JsonResponse({"MESSAGE": "KEY_ERROR"}, status=400)
except Room.DoesNotExist:
return JsonResponse({"MESSAGE": "DOESNOT_EXIST_ROOM"}, status=400)
유저가 입력한 정보를 프론트엔드로 부터 데이터를 받아 데이터베이스에 예약 정보를 저장하는 로직을 구현했다.
DetailReservation GET
class DetailReservationView(View):
@signin_decorator
def get(self, request, reservation_number):
# user = User.objects.get(id = 7)
reservation = Reservation.objects.select_related("room") \
.prefetch_related("room__image_set") \
.get(user =request.user, number = reservation_number)
result = {
'reservation_number' : reservation.number,
'user_name' : reservation.user.last_name + " " + reservation.user.first_name,
'room' : reservation.room.name,
'price' : reservation.price,
'people' : reservation.people,
'check_in' : reservation.check_in,
'check_out' : reservation.check_out,
'images' : [image.url for image in reservation.room.image_set.all()],
'description' : reservation.room.description,
'address' : reservation.room.address + " " + reservation.room.detail_address,
'latitude' : reservation.room.latitude,
'longitude' : reservation.room.longitude
}
return JsonResponse({"RESULT": result}, status=200)
모든 예약된 리스트에서 하나의 예약 정보를 받고자 할 경우 Path parameter를 이용해서 reservation_number를 넘기고 해당 reservation_number에 해당하는 예약정보를 출력하는 로직을 구현했다.
DetailReservation DETELE
@signin_decorator
def delete(self, request, reservation_number):
try:
# user = User.objects.get(id = 8)
Reservation.objects.get(user=request.user, number=reservation_number).delete()
return JsonResponse({'MESSAGE': 'RESERVATION_CANCEL'}, status=200)
except Reservation.DoesNotExist:
return JsonResponse({'MESSAGE': 'DOESNOT_EXIST_RESERVATION'}, status=400)
예약 상세페이지에서 예약 취소 버튼을 누를 경우 path parameter로 들어가 reservation_number 데이터를 이용해서 해당 예약 정보를 DB에서 삭제하는 로직을 구현했다.