728x90
제품 리스트 API구현을 마치고 상세페이지 API구현을 하게 되었다.
우선 상세페이지 view는 path 파라미터로 받아서 어떤 상품인지 식별하게 했다.
urlpatterns = [
path('', ProductsView.as_view()),
path('/<int:product_id>', ProductDetailView.as_view())
]
프론트에 던져 줄 데이터는
상품 아이디, 이름, 가격, 좋아요 수, 이미지 총 5개 였다.
class ProductDetailView(View):
def get(self, request, product_id):
if not (Product.objects.filter(id=product_id).exists()):
return JsonResponse({'MESSAGE': 'NOT_FOUND'}, status=404)
product = Product.objects.annotate(likes=Count("userproductlike")).get(id=product_id)
results = {
'id':product.id,
'name':product.name,
'price':int(product.price),
'like': product.likes,
'images':[image.url for image in product.image_set.all()],
}
return JsonResponse({'results': results}, status=200)
간단하게 구현할 수 있었다.
path파라미터로 받은 값으로 상품을 조회하고 없으면 404에러를 반환하고 있으면 다음 분기를 실행하게 했다.
5가지 항목 중 좋아요 수가 문제였다.
좋아요는 Many To Many 관계로 엮여있고 그 수를 세서 값으로 던져줘야했다.
# 상품과 좋아요 관계 테이블
class Product(models.Model):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=10, decimal_places=3)
discount_percent = models.DecimalField(max_digits=5, decimal_places=3,blank=True)
is_new = models.BooleanField(default=False)
category = models.ForeignKey('category', on_delete=models.SET_NULL,null=True)
like = models.ManyToManyField(User,through='Userproductlike',related_name='products')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'products'
class UserProductLike(models.Model):
user = models.ForeignKey(User,on_delete=models.CASCADE)
product = models.ForeignKey('product',on_delete=models.CASCADE)
class Meta:
db_table = 'userproductlikes'
그래서 annotate 문법을 사용했다.
annotate는 테이블에 컬럼을 추가할 수 있는 문법이다.
이번 경우에는 likes라는 컬럼을 추가했고 값으로는 좋아요 숫자를 넣어주었다.
product = Product.objects.annotate(likes=Count("userproductlike")).get(id=product_id)
그래서 깔끔하게 likes 항목에 product.likes를 넣어주었다.
results = {
'id':product.id,
'name':product.name,
'price':int(product.price),
'like': product.likes,
'images':[image.url for image in product.image_set.all()],
}
위 코드는 총 3번의 쿼리문을 날렸다.
이번에도 성능을 올리려고 prefetch_related를 사용해서 image_set을 적용하려 했으나
똑같이 쿼리가 3번 호출됐다.
상품이 하나이기 때문에 prefetch의 효과가 없었다.
그리고 마무리를 하려했으나 리뷰가 추가되었다...
'DotFriends' 카테고리의 다른 글
⚫️Dotfriends 페이징 기능 쿼리 성능 향상 시키기 (0) | 2021.10.16 |
---|---|
🚀 상품 리스트 조회 API분기 줄이기 (0) | 2021.09.25 |
📌 쿼리 파라미터 입력값에 따른 500에러 막기 (0) | 2021.09.24 |
⚫️ DotFriends 프로젝트 후기 (0) | 2021.09.12 |
prefetch_related로 성능 향상하기 (0) | 2021.09.05 |