product.views.py
import json
from django.core.paginator import Paginator
from django.views import View
from django.http import (
JsonResponse,
HttpResponse
)
from product.models import (
Category,
Gender,
Sport,
Tag,
Review,
Product,
Color,
MiddleColorImage,
Image,
Size,
ProductSize,
Detail,
)
from account.models import Account
from account.utils import login_required
class SportView(View):
def get(self, request):
all_sprots_category = Sport.objects.all()
sport_list = [sport.name for sport in all_sprots_category]
return JsonResponse({"Sports": sport_list}, status=200)
class TotalView(View):
def get(self, request):
target_id = request.GET.get("id", None)
all_sports = Product.objects.prefetch_related('gender','sport','tag','image_set','detail','size','color').all()[:40]
product_list = [
{
'id' : shoe.id,
'name' : shoe.name,
'sport' : shoe.sport.name,
'tag' : shoe.tag.name,
'gender' : shoe.gender.name,
'use' : shoe.detail.purpose,
'original_price' : round(shoe.price),
'sale_price' : round(shoe.discount_price),
'sizes' : [size_info.name for size_info in shoe.size.all()],
'color' : [color.name for color in shoe.color.all()][0],
'main_images' : [img.img_url for img in shoe.image_set.filter(product_id=shoe.id)[:2]],
'sub_images' : [sub_img.img_url for sub_img in shoe.image_set.filter(product_id = shoe.id,is_sub_img=True)],
'color_number' : len(shoe.image_set.filter(product_id = shoe.id,is_sub_img=True))
} for shoe in all_sports]
return JsonResponse({"total_product":product_list}, status=200)
class DetailView(View):
def get(self, request):
target_id = request.GET.get("id", None)
all_sport = Product.objects.prefetch_related('gender','sport','tag','image_set','detail','size','color').filter(id=target_id)
product_list = [
{
'id' : shoe.id,
'name' : shoe.name,
'code' : shoe.code,
'sport' : shoe.sport.name,
'tag' : shoe.tag.name,
'gender' : shoe.gender.name,
'use' : shoe.detail.purpose,
'material' : shoe.detail.material,
'origin' : shoe.detail.origin,
'manufacture_date' : shoe.detail.manufacturing_date,
'description' : shoe.description,
'original_price' : round(shoe.price),
'sale_price' : round(shoe.discount_price),
'sizes' : [size_info.name for size_info in shoe.size.all()],
'color' : [color.name for color in shoe.color.all()][0],
'main_image' : [img.img_url for img in shoe.image_set.filter(product_id=shoe.id)[:1]],
'detail_images' : [detail_img.img_url.replace("/720/","/60/") for detail_img in shoe.image_set.filter(product_id = shoe.id)],
'sub_images' : [sub_img.img_url for sub_img in shoe.image_set.filter(product_id = shoe.id,is_sub_img=True)],
'color_number' : len(shoe.image_set.filter(product_id = shoe.id,is_sub_img=True)),
'main_description' : shoe.description.split("•")[0],
'sub_description' : ["•"+sub_desc for sub_desc in shoe.description.split("•")[1:]],
} for shoe in all_sport]
product_num = request.GET.get("id", None)
if product_num == None :
review_result = [{
'product_code' : "",
'date' : "",
'comment' : "첫 리뷰를 남겨주세요",
'user_account' : "",
}]
else :
Reviews = Review.objects.filter(product_id = product_num).order_by('-date')
review_result = [{
'product_code' : review.product.code,
'date' : str(review.date).split(" ")[0],
'comment' : review.comment,
'user_account' : review.account.user_account
}for review in Reviews]
return JsonResponse({"product_detail":product_list,"product_review" : review_result}, status=200)
class FilterView(View):
def get(self, request):
filters = {}
sport_id = request.GET.get("sport", None)
color_id = request.GET.get("color", None)
size_id = request.GET.get("size", None)
price_id = request.GET.get("price", None)
if Sport.objects.filter(name = sport_id):
filters['sport'] = Sport.objects.prefetch_related("sport_product").filter(name = sport_id)[0].id
if Color.objects.filter(name = color_id):
filters['color'] = Color.objects.prefetch_related("colors_product").filter(name = color_id)[0].id
if Size.objects.filter(name = size_id):
filters['size'] = Size.objects.filter(name = size_id)[0].id
if price_id:
if "미만" in price_id:
price_id = price_id[:-3]
price_id = price_id.replace(",","")
price_id = int(price_id)
filters['price__lt'] = price_id
elif "초과" in price_id:
price_id = price_id[:-3]
price_id = price_id.replace(",","")
price_id = int(price_id)
filters['price__gt'] = price_id
else:
p = price_id.split(" ~ ")
minimum = p[0]
maximum = p[1]
minimum = minimum.replace(",","")
maximum = maximum.replace(",","")
minimum = int(minimum)
maximum = int(maximum)
filters['price__gt'] = minimum
filters['price__lt'] = maximum
product_list = Product.objects.filter(**filters)
shoe_list = [{
'id' : shoe.id,
'sport' : shoe.sport.name,
'tag' : shoe.tag.name,
'price' : round(shoe.price),
'name' : shoe.name,
'code' : shoe.code,
'sale_price' : round(shoe.discount_price),
'img' : [img.img_url for img in shoe.image_set.filter(product_id=shoe.id)[:2]],
'sub_img' : [sub_img.img_url for sub_img in shoe.image_set.filter(product_id = shoe.id,is_sub_img=True)],
'colors' : len(shoe.image_set.filter(product_id = shoe.id,is_sub_img=True)),
}for shoe in product_list]
return JsonResponse({'Shoes':shoe_list}, status=200)
class SportView(View):
def get(self, request):
sport_id = request.GET.get("sport", None)
sport = Sport.objects.prefetch_related('sport_product').filter(name = sport_id)
product_list = sport[0].sport_prouct.all()
shoe_list = [
{
'id' : product.id,
'name' : product.name,
'sport' : product.sport.name,
'tag' : product.tag.name,
'gender' : product.gender.name,
'use' : product.detail.purpose,
'original_price' : round(product.price),
'sale_price' : round(product.discount_price),
'main_images' : [img.img_url for img in product.image_set.filter(product_id=product.id)[:2]],
'sub_images' : [sub_img.img_url for sub_img in product.image_set.filter(product_id = product.id,is_sub_img=True)],
'product_color_len': len(product.image_set.filter(product_id = product.id,is_sub_img=True))
} for product in product_list]
return JsonResponse({"total_product":shoe_list}, status=200)
class ReviewView(View):
#@login_required
def post(self, request):
review_data = json.loads(request.body)
product_name = review_data['product_id']
code_id = Product.objects.get(id=product_name).id
Review(
product_id = code_id,
comment = review_data['comment'],
point = 5
).save()
return JsonResponse({'message': "success"}, status=200)
class MainView(View):
def get(self, request):
target_id = request.GET.get("id", None)
all_sport = Product.objects.prefetch_related('gender','sport','tag','image_set','detail','size','color').all()[:12]
product_list = [
{
'id' : shoe.id,
'product_name' : shoe.name,
'product_sport' : shoe.sport.name,
'product_tag' : shoe.tag.name,
'product_price' : round(shoe.price),
'product_discount_price' : round(shoe.discount_price),
'product_img' : [img.img_url for img in shoe.image_set.filter(product_id=shoe.id)[:1]],
'product_color_len' : len(shoe.image_set.filter(product_id = shoe.id,is_sub_img=True))
} for shoe in all_sport]
return JsonResponse({"total_product":product_list}, status=200)
- 실제로 select_related, prefetch_related를 사용하였다.
- 각 Table들의 연결을 통해 다양하게 접근하여 원하는 데이터를 조회할 수 있다는 점이 재밌게 느껴졌다.
- 처음에 역참조에 대한 부분이 이해가 되지 않았지만 실제로 사용을 해보고 shell을 통해 실제 데이터를 불러오면서 이해가 되기 시작하였다.
- select_related, prefetch_related를 사용하며 성능에 대한 생각을 하게 되었다.
- 현재 우리 웹사이트의 경우 DB에 저장된 데이터가 많지 않고 사용자가 거의 없기 때문에 피부로 와닿지는 않지만 DB에 어떠한 방법으로 접근하는지에 따라 속도가 크게 달라진다는 부분을 알게 되었다.