ProductView
class CategoryView(View):
def get(self, reqeust):
menus = Menu.objects.all().prefetch_related('maincategory_set', 'maincategory_set__category_set')
category_list = [{
'menu_id' : menu.id,
'menu_name' : menu.name,
'main_category': [{
'main_category_id' : main_category.id,
'main_category_name': main_category.name,
'category' : [{
'category_id' : category.id,
'category_name': category.name,
} for category in main_category.category_set.all()]
} for main_category in menu.maincategory_set.all()]
} for menu in menus]
return JsonResponse({"results" : category_list}, status=200)
class RecommendationView(View):
def get(self, request):
limit = int(request.GET.get('limit', 4))
offset = int(request.GET.get('offset',0))
recommendations = Product.objects.all().prefetch_related('productimage_set').order_by("?")[offset:offset+limit]
product_recommendation = [{
"id" : recommendation.id,
"img_url": [image.img_url for image in recommendation.productimage_set.all()],
"name" : recommendation.name,
"price" : recommendation.price,
} for recommendation in recommendations]
return JsonResponse({'results' : product_recommendation}, status=200)
:: Q 객체 & Annotate
class ProductListView(View):
def get(self, request):
menu = request.GET.get('menu', None)
main_category = request.GET.get('main_category', None)
category = request.GET.get('category', None)
search = request.GET.get('search')
sort = request.GET.get('sort', 'new')
limit = int(request.GET.get('limit', 12))
offset = int(request.GET.get('offset',0))
q = Q()
if menu:
q &= Q(categoryproduct__category__main_category__menu__id = menu)
if main_category:
q &= Q(categoryproduct__category__main_category__id = main_category)
if category:
q &= Q(categoryproduct__category__id = category)
if search:
q &= Q(name__icontains = search)
sort_type = {
'reviews' : '-total_reviews',
'sales' : '-total_sales',
'new' : '-id',
'price_desc': '-price',
'price_asc' : 'price'
}
products = Product.objects.filter(q).annotate(total_sales=Sum('orderitem__quantity', distinct=True))\
.annotate(total_reviews=Count('review__id', distinct=True))\
.order_by(sort_type.get(sort))[offset:offset+limit]
products_list = [{
"id" : product.id,
"name" : product.name,
"price" : product.price,
"discount_rate": product.discount_rate,
"novel" : True if product in Product.objects.all().order_by('-id')[:2] else False,
"sale_or_not" : False if product.discount_rate == 0 else True,
"img_url" : [image.img_url for image in product.productimage_set.all()],
} for product in products]
return JsonResponse({'results': products_list}, status=200)
:: Dictionary Unpacking
추후 정리 후 추가 예정
:: get_or_create() Method + if not created:
@access_token_check
def post(self, request):
try:
data = json.loads(request.body)
user = request.user
product_id = int(data['product_id'])
quantity = int(data['quantity'])
cart, created = Cart.objects.get_or_create(
user_id = user.id,
product_id = product_id,
defaults={"quantity" : quantity}
)
if not created:
cart.quantity += quantity
cart.save()
return JsonResponse({"message" : "SUCCESS"}, status=201)
except KeyError:
return JsonResponse({"message" : "KEY_ERROR"}, status=400)
:: request.Get.getlist() // Query Parameter
@access_token_check
def delete(self, request):
user = request.user.id
cart_ids = request.GET.getlist('cart_id')
Cart.objects.filter(id__in=cart_ids, user_id=user).delete()
return JsonResponse({"message" : "SUCCESS"}, status=200)
:: Aggregate (평균)
def get(self, request, product_id):
limit = int(request.GET.get('limit', 5))
offset = int(request.GET.get('offset',0))
reviews = Review.objects.filter(product_id = product_id)
total_reviews = reviews.count()
average_rates = reviews.aggregate(avg_rating=Avg('rating'))["avg_rating"] or 0
review_list = [{
"reviewId" : review.id,
"productId": product_id,
"account" : review.user.account,
"content" : review.content,
"rating" : review.rating,
"date" : review.created_at,
} for review in reviews[offset:offset+limit]]
return JsonResponse({"totalReviews" : total_reviews, "averageRating": round(float(average_rates), 1), "reviews" : review_list}, status=200)
:: ReviewView DELETE & URLS.py(***)
@access_token_check
def delete(self, request, product_id, review_id):
try:
user = request.user.id
Review.objects.get(id = review_id, user_id = user).delete()
return JsonResponse({"message" : "DELETE_SUCCESS"}, status=200)
except Review.DoesNotExist:
return JsonResponse({"message" : "CONTENT_DOES_NOT_EXIST"}, status=404)
from django.urls import path
from reviews.views import ReviewView
urlpatterns = [
path('/<int:product_id>/reviews', ReviewView.as_view()),
path('/<int:product_id>/reviews/<int:review_id>', ReviewView.as_view()),
]