[PROJECT] AIRBNB CLONING #4
Room Detail API
Room Detail 페이지에서 User가 Superhost인지의 여부, User의 이미지, Amenity와 Facility와 같은 편의시설, Reservation, 체크인 날짜와 숙소의 숙박이 가능한 날짜, 그리고 리뷰와 리뷰에 들어갈 이미지, 호스팅 지역, 숙소 규칙 등의 정보가 들어가야 합니다. 여러개의 API가 한 페이지에 합쳐져 잘게 쪼개서 진행했습니다.
디데일 API 코드는 다음과 같습니다.
config/urls
from django.urls import path, include
urlpatterns = [
path("rooms", include('rooms.urls')),
]
rooms/urls
from django.urls import path
from rooms.views import RoomDetailView
urlpatterns = [
path('/<int:room_id>', RoomDetailView.as_view()),
]
Path Paramter를 적용했습니다. id가 1번인 room의 uri는 /rooms/1
이 됩니다.
rooms/views
from django.http import JsonResponse
from django.views import View
from rooms.models import Room, RoomAmenity, RoomHouseRule
class RoomDetailView(View):
def get(self, request, room_id):
if not Room.objects.filter(id=room_id).exists():
return JsonResponse({'message': 'ROOM_DOES_NOT_EXIST'}, status=404)
room = Room.objects.select_related('category')\
.prefetch_related('room_amenities', 'room_houserules', 'room_images', 'room_schedules').get(id=room_id)
result = {
"name" : room.name,
"description" : room.description,
"district" : room.district,
"neighberhood" : room.neighberhood,
"price" : float(room.price),
"address" : room.address,
"guests" : int(room.guests),
"beds" : room.beds,
"bedrooms" : room.bedrooms,
"baths" : room.baths,
"latitute" : float(room.latitute),
"longitute" : float(room.longitute),
"host" : room.user.nickname,
"host_image" : room.user.profile_image,
"category" : room.category.type,
"room_images_url" : [image.image_url for image in room.room_images.all()],
"check_in" : [schedule.check_in for schedule in room.room_schedules.all()],
"room_amenities" : [{
"amenity_id" : amenity.id,
"amenity_name" : amenity.amenity.name,
"amenity_icon_url" : amenity.amenity.icon_url,
}for amenity in RoomAmenity.objects.filter(room_id=room_id)],
"check_in_time" : room.check_in_time,
"check_out_time" : room.check_out_time,
"house_rules" : [{
"room_rules" : rules.house_rule.name,
"rules_icon_url" : rules.house_rule.icon_url,
}for rules in RoomHouseRule.objects.filter(room_id=room_id)]
}
return JsonResponse({'message' : result}, status=200)
Django의 ORM을 최적화하기 위해 selected_related
와 prefetch_related
를 사용하였습니다.
ORM
ORM은 객체(object)와 관계형 데이터베이스(Relational Database)의 데이터를 매핑해주는 것을 의미합니다. 요약하자면 데이터베이스와 객체지향 프로그래밍 언어간의 호환되지 않는 데이터를 변환해주는 프로그래밍 기법입니다.
Django ORM을 사용할 때 Query 개수를 줄일 수 있는 방법으로 select_related
와 prefetch_related
가 있습니다. 이를 활용하면 불로온 데이터가 모두 캐시에 남아있게 되어 DB에 히트하는 수를 줄여 성능을 향상시킬 수 있는데요!
selected_related
selected_related
는 SQL Query 문의 JOIN 을 사용하여 foreign-key(one to one, many to one)를 사용하여 정참조할 때 사용하며 QuerySet을 가져올 때, 미리 related objects까지 불러오는 함수입니다.
이를 활용하여 데이터베이스에 접근하는 빈도를 줄일 수 있습니다.
prefetch_related
selected_related
는 하나의 Query로 related Objects들을 불러오지만, Prefetch_related
는 main query가 실행이 된 후 별도의 query가 실행이 됩니다.
다음은 몇 개의 쿼리가 찍혔는지, 몇 초가 결렸는지를 확인한 사진입니다.
Author And Source
이 문제에 관하여([PROJECT] AIRBNB CLONING #4), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tritny6516/PROJECT-AIRBNB-CLONING-4저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)