마이리얼트립 클론④API-Products

박민하·2022년 7월 18일
0

PROJECT

목록 보기
17/17
post-thumbnail

✅ 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)
profile
backend developer 🐌

0개의 댓글