DetailView

class DetailView(View):
    def get(self, request, details_id):
        try:
            product   = Product.objects.get(id=details_id)
            images    = [i['url'] for i in product.productimage_set.filter(product_id=product.id).values('url')]
            po_sort   = ProductOption.objects.all().order_by('size_id')
            size_quan = [{"sizeName" : po.size.type, "quantity" : po.quantity} for po in po_sort.filter(product_id=product.id)]
            results   = {
                "product_id"        : product.id,
                "price"             : product.price,
                "product_images"    : images,
                "sub_title"         : product.sub_title,
                "title"             : product.title,
                "price"             : int(product.price),
                "eco_friendly"      : product.eco_friendly,
                "size_quan"         : size_quan,
                "description_title" : product.description_title,
                "description"       : product.description,
                "current_color"     : product.current_color,
                "serial"            : product.serial
            }

            return JsonResponse({'results' : results}, status = 200)

        except KeyError:
            return JsonResponse({"message" : "KEY_ERROR"}, status=401)

url

from django.urls    import path
from products.views import ProductListView, DetailView

app_name = 'products'
urlpatterns = [
    path('', ProductListView.as_view()),
    path('/details/<int:details_id>', DetailView.as_view()),
]
# core에 utills.py로 저장
import jwt

from django.conf  import settings
from django.http  import JsonResponse

from users.models import User

def login_decorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            access_token = request.headers.get('Authorization', None)
            data = jwt.decode(access_token, settings.SECRET_KEY, algorithms=settings.ALGORITHM)
            request.user = User.objects.get(id=data['id'])
                        
        except jwt.exceptions.DecodeError:
            return JsonResponse({'message' : 'INVALID_TOKEN'}, status = 401)            

        except User.DoesNotExist:
            return JsonResponse({'message' : 'UNKNOWN_USER'}, status = 401)

        return func(self, request, *args, **kwargs)

    return wrapper
from django.urls    import path
from orders.views import ReviewView

app_name = 'orders'
urlpatterns = [
    path('/details/<int:details_id>', ReviewView.as_view()),
]
import json

from json.decoder       import JSONDecodeError
from django.http        import JsonResponse
from django.views       import View
from django.core.exceptions import MultipleObjectsReturned
from django.db.models   import Avg
from django.utils.dateformat import DateFormat

from orders.models      import ShoppingCart
from products.models    import ProductOption
from core.utils         import login_required
from orders.models    import Review

class CartListView(View):
    @login_required
    def get(self, request):
        results = [{
            "cart_id"             : cart.id,
            "product_id"          : cart.product_option.product.id,
            "user_id"             : cart.user_id,
            "product_title"       : cart.product_option.product.title,
            "serial"              : cart.product_option.product.serial,
            "size"                : cart.product_option.size.type,
            "quantity"            : cart.quantity,
            "price"               : float(cart.product_option.product.price * cart.quantity),
            "thumbnail_image_url" : cart.product_option.product.thumbnail_image_url,
		} for cart in ShoppingCart.objects.filter(user_id=request.user.id)\
                                          .select_related('product_option__product','product_option__size')]
        
        return JsonResponse({"results" : results}, status=200)

    @login_required
    def post(self, request):
        try:
            data = json.loads(request.body)
            product_option = ProductOption.objects.get(product_id=data['product_id'], size__type=data['size'])
            
            if data['quantity'] < 1 or data['quantity'] > product_option.quantity:
                return JsonResponse({"message" : "INVALID_QUANTITY"}, status=400)

            ShoppingCart.objects.create(
                user_id           = request.user.id,
                product_option_id = product_option.id,
                quantity          = data['quantity'],
            )
            return JsonResponse({"message" : "SUCCESS"}, status=201)
            
        except JSONDecodeError:
            return JsonResponse({"message" : "JSON_DECODE_ERROR"}, status=400)
        except KeyError:
            return JsonResponse({"message" : "KEY_ERROR"}, status=400)
        except ProductOption.DoesNotExist:
            return JsonResponse({"message": "DOES_NOT_EXIST_PRODUCT_OPTION"}, status=400)

    @login_required
    def delete(self, request):
        try:
            data = json.loads(request.body)
            ShoppingCart.objects.get(id=data['cart_id']).delete()

            return JsonResponse({"message" : "SUCCESS"}, status=204)

        except JSONDecodeError:
            return JsonResponse({"message" : "JSON_DECODE_ERROR"}, status=400)
        except KeyError:
            return JsonResponse({"message" : "KEY_ERROR"}, status=400)
        except ProductOption.DoesNotExist:
            return JsonResponse({"message": "DOES_NOT_EXIST_PRODUCT_OPTION"}, status=400)

class ReviewView(View):
    #@login_required
    def get(self, request, details_id):
        try:
            review = Review.objects.get(id=details_id)
            review2 = Review.objects.filter(product_option__product__id=details_id)
            Avg_rating = review2.aggregate(Avg('rating'))['rating__avg']

            if Avg_rating == None:
                Avg_rating = "None"
            else:
                Avg_rating = int(Avg_rating)

            if review.rating == None:
                rating = "None"    
            else:
                rating = int(review.rating)

            results = {
                "total_review" : len(review2),
                "Avg_rating" : Avg_rating,
                "title" : review.title,
                "rating" : rating,
                "name" : review.user.name,
                "date" : DateFormat(review.created_at).format('Y.m.d'),
                "serial" : review.product_option.product.serial,
                "size" : review.product_option.size.type,
                "text" : review.text,
                "image" : review.reviewimage_set.filter(id=details_id).values('url')[0]
            }
            
            return JsonResponse({'results' : results}, status = 200)
        except Review.DoesNotExist:
            return JsonResponse({'message' : "Review does not exist"}, status = 400)
        
        except MultipleObjectsReturned:
            return JsonResponse({'message' : "MultipleObjectsReturned"}, status = 400)

        except KeyError:
            return JsonResponse({'message': "KEY_ERROR"}, status = 401)
reviews = Review.objects.filter(product_option__product__id=details_id)
            Avg_rating = reviews.aggregate(Avg('rating'))['rating__avg']
            results = [{
                "total_review" : len(reviews),
                "Avg_rating" : int(Avg_rating),
                "title" : review.title,
                "rating" : int(review.rating),
                "name" : review.user.name,
                "date" : DateFormat(review.created_at).format('Y.m.d'),
                "serial" : review.product_option.product.serial,
                "size" : review.product_option.size.type,
                "text" : review.text,
                "image" : ReviewImage.objects.filter(review_id=review.id)[0].url
            } for review in reviews if ReviewImage.objects.filter(
                review_id=review.id)[0].url]
@login_required
    def post(self, request, product_id):
        try:
            data   = json.loads(request.body)

            title  = data["title"]
            rating = data["rating"]
            text   = data["text"]
            image  = data["image"]
           
            Review.objects.create(
                title   = title,
                rating  = rating,
                text    = text,
                user_id = request.user.id, 
                product_option_id = [po.value('product_option') for po in Order.objects.filter(user_id=request.user.id)]
            )

            ReviewImage.objects.create(
                url = image
            )

            return JsonResponse({"message" : "SUCCESS"}, statue=201)

        except KeyError:
            return JsonResponse({"message" : "KEY_ERROR"}, status=401)
class ReviewView(View):
    @login_required
    def get(self, request, product_id):
        reviews = Review.objects.filter(product_option__product__id=product_id)
        Avg_rating = reviews.aggregate(Avg('rating'))['rating__avg']
        results = [{
            "total_review" : len(reviews),
            "Avg_rating" : int(Avg_rating),
            "title" : review.title,
            "rating" : int(review.rating),
            "name" : review.user.name,
            "date" : DateFormat(review.created_at).format('Y.m.d'),
            "serial" : review.product_option.product.serial,
            "size" : review.product_option.size.type,
            "text" : review.text,
            "image" : ReviewImage.objects.filter(review_id=review.id)[0].url
        } for review in reviews if ReviewImage.objects.filter(
            review_id=review.id)[0].url] 

        return JsonResponse({'results' : results}, status = 200)

ppt 준비