adidas clone 프로젝트 과정(3)

JM·2020년 7월 19일
0

Project

목록 보기
4/11
post-custom-banner

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에 어떠한 방법으로 접근하는지에 따라 속도가 크게 달라진다는 부분을 알게 되었다.
post-custom-banner

0개의 댓글