✅ View
✔ import
import pandas
import json
from django.http import JsonResponse
from django.views import View
from django.db.models import Q, Min, Avg, Count, IntegerField, Max
from django.db.models.functions import Coalesce
from datetime import datetime, timedelta
from products.models import Product, Room, Amenity
from orders.models import Reservation
from users.models import Review
✔ 상품페이지
class ProductView(View):
def get(self, request, product_id):
try:
start_date = request.GET.get('start_date')
end_date = request.GET.get('end_date')
product = Product.objects.annotate(
rating = Coalesce(Avg('review__rating'),0.0),
review_count = Coalesce(Count('review__id'),0)
).get(id = product_id)
product_price = Product.objects.aggregate(price = \
Coalesce(Min('room__price'),0,output_field = IntegerField()))['price']
reservations = Reservation.objects.filter(room__product = product)
rooms = Room.objects.filter(product = product)
search_date = set(pandas.date_range(start_date,end_date)[:-1])
is_sold_out = True
for room in rooms:
for reservation in reservations:
reservation_date = set(pandas.date_range(reservation.start_date,reservation.end_date)[:-1])
if search_date & reservation_date:
room.quantity -= 1
if bool(room.quantity) == True:
is_sold_out = False
result = {
'id' : product.id,
'name' : product.name,
'grade' : product.grade if product.grade else 0,
'address' : product.address,
'check_in' : product.check_in,
'check_out' : product.check_out,
'latitude' : product.latitude,
'longtitude' : product.longtitude,
'price' : product_price * len(search_date),
'rating' : product.rating,
'review_count' : product.review_count,
'images' : [
{
'url' : image.url,
'is_main' : image.is_main
}for image in product.productimage_set.all()
],
'is_sold_out' : is_sold_out
}
return JsonResponse(result, status = 200)
except Product.DoesNotExist:
return JsonResponse({'message' : 'Invalid Product'}, status = 400)
✔ 리뷰페이지
class ReviewsView(View):
def get(self, request, product_id):
sort_key = request.GET.get('sort', 'newest')
rating = request.GET.get('rating')
has_image = request.GET.get('has_image')
offset = request.GET.get('offset', 0)
limit = request.GET.get('limit', 10)
sort_dict = {
'newest' : '-updated_at',
'random' : '?',
'low_rating' : 'rating',
'high_rating' : '-rating'
}
q = Q(product_id = product_id)
if rating:
q &= Q(rating__exact = rating)
if has_image:
q &= Q(image_url__isnull = False)
reviews = Review.objects.filter(q).order_by(sort_dict.get(sort_key))[offset:offset + limit]
result = [
{
'id' : review.id,
'product_id' : review.product_id,
'user_name' : review.user.name,
'rating' : review.rating,
'content' : review.content,
'image_url' : review.image_url,
'updated_at' : review.updated_at.date(),
}for review in reviews
]
return JsonResponse({'reviews' : result}, status = 200)
✔ 방 상세 페이지
class RoomsView(View):
def get(self, request, product_id):
start_date = request.GET.get('start_date', datetime.now().strftime("%Y-%m-%d"))
end_date = request.GET.get('end_date')
guests = int(request.GET.get('guests',2))
if not end_date:
join_date = datetime.now()+ timedelta(days=1)
end_date = join_date.strftime("%Y-%m-%d")
search_date = set(pandas.date_range(start_date,end_date)[:-1])
q = Q(product_id = product_id)
q &= Q(max_guest__gte = guests)
rooms = Room.objects.filter(q).prefetch_related('reservation_set')
list1 = []
for room in rooms:
for reservation in room.reservation_set.all():
reservation_date = set(pandas.date_range(reservation.start_date,reservation.end_date)[:-1])
if search_date & reservation_date:
room.quantity -= 1
if not room.quantity:
list1.append(room.id)
p &= Q(id__in = list1)
rooms = Room.objects.filter(q).exclude(p).order_by('price').prefetch_related('roomimage_set')
rooms_result = [
{
'id' : room.id,
'name' : room.name,
'price' : int(room.price) * len(search_date),
'min_guests' : room.min_guest,
'max_guests' : room.max_guest,
'size' : room.size,
'images' : [
{
'id' : image.id,
'url' : image.url,
'is_main' : image.is_main
}for image in room.roomimage_set.order_by('is_main')
]
}for room in rooms]
return JsonResponse({'rooms' : rooms_result}, status = 200)