1. 혼자 만들어보는 Zara - 상품 상세리스트

Kiyong Lee·2021년 12월 13일
0

개인프로젝트

목록 보기
8/9

혼자 만들어보는 Zara - 상품상세리스트


1. views.py

class DetailProductView(View) :
    def get(self, request, product_id) :
        try :
            product         = Product.objects.prefetch_related('productimage_set').get(id=product_id)
            detail_products = DetailProduct.objects.select_related('size', 'color', 'product').filter(product=product)
            
            data_set = [{
                'id'     : product_id,
                'name'   : product.name,
                'price'  : product.price,
                'detail' : [{
                    'color_id'   : detail['color'],
                    'color_name' : Color.objects.get(id=detail['color']).color,
                    'size' : [{
                        'size_id'   : size['size'],
                        'size_name' : Size.objects.get(id=size['size']).size
                    }for size in detail_products.filter(color_id=detail['color']).values('size')]
                }for detail in detail_products.values('color').distinct()],
                'images' : [{
                    'id'  : image.id,
                    'url' : image.url
                }for image in product.productimage_set.all()]
            }]
            
            return JsonResponse({'data_set' : data_set}, status=200)
        
        except TypeError :
            return JsonResponse({'message' : 'TYPE_ERROR'}, status=400)
        
        except Product.DoesNotExist :
            return JsonResponse({'message' : 'PRODUCT_DOES_NOT_EXIST'}, status=400)

2. 구현 설명

detail_products에서 filter조건에 Path Parameterproduct_id를 받으려 했으나,
product에서 역참조를 통해 상품상세페이지의 이미지를 가져와야했기 때문에
product를 선언해야하는 상황이어서 객체로 받게 되었습니다.

prefetch_related라서 product 객체를 가져오고 쿼리문을 실행하긴 하지만
불러온 정보를 최대한 사용하는 것이 맞다고 판단했습니다.

가장 큰 문제는 색상-사이즈에 대한 문제였습니다.
Zara 홈페이지를 보니 옷 색상마다 사이즈를 선택할 수 있어서 색상에 대한 반복문 후
그에 따라 사이즈를 선택하게 했습니다.

색상3개와 사이즈3개의 경우의 수는 총 9가지인데, detail_products로 반복문을
돌리면 색상 3개만 필요한데 9번이 돌아가 필요없는 작업을 하게 되는 것이며
values를 통해 접근할 수 밖에 없었습니다.

그렇다보니 색상과 사이즈의 명을 가져올 때 마다 어쩔 수 없이 쿼리문이 실행되어
select_related를 사용했음에도 불구하고 N+1 Problem이 발생했습니다.

select_related('color__color') 같이 사용하려 했으나, select_related
참조하고 있는 키 값에만 접근 가능해서 불가능하기 때문에 detail_products의 결과에서
색상과 사이즈로 한 번 더 쪼개서 사용할 수 밖에 없었습니다.


다음 포스트는 update_or_create 혹은 F를 이용한 수정을 해볼 생각입니다.

profile
ISTJ인 K-개발자

0개의 댓글

관련 채용 정보