1. MainPageView
우리팀은 메인페이지에서 신상품 ,베스트 상품, 친환경 상품(그린)을 각각 8개씩 보여주기로 했다.
신상품은 이력관리용으로 넣어놓은 created_at 컬럼을 활용하고, 베스트와 그린은 직접 지정했기 때문에 그냥 필터로 뽑아내고 최신순으로 정렬해서 8개씩 슬라이싱해서 보내주는 것으로 했다.
메인페이지를 다른 앱으로 분리해서 만들어야 하나 고민을 했는데 메인에서도 결국 상품에 관련된 데이터만 활용하기 때문에 상품리스트와 상세페이지와 같은 product의 views.py에 정의했다.
그리고 세 가지 리스트 모두 반환해주는 값이 같기 때문에 get_list라는 함수를 정의해서 각 리스트를 반환했다.
class MainPageView(View):
def get(self, request):
def get_list(products):
product_list = [{
'id' : product.id,
'name' : product.name,
'price' : product.price,
'is_green': product.is_green,
'is_best' : product.is_best,
'images' : [{
'id' : image.id,
'url': image.url
} for image in product.productimage_set.all()]
} for product in products]
return product_list
new_products = Product.objects.all().order_by('-created_at')[:8]
best_products = Product.objects.filter(is_best = True).order_by('-created_at')[:8]
green_products = Product.objects.filter(is_green = True).order_by('-created_at')[:8]
return JsonResponse({
'new_products' : get_list(new_products),
'best_products' : get_list(best_products),
'green_products': get_list(green_products)}, status=200)
2. ProductDetailView
상품 상세정보 페이지는 상품 id(product_id)를 path parameter로 받아서 해당 상품의 정보를 응답해주도록 했다.
배민문방구 상세페이지를 보면 이름, 상품 이미지, best, green정보, 가격, 옵션을 보여주기 때문에 해당 정보들을 응답으로 보내주었다.
상품의 id가 존재하지 않는다면 상품이 존재하지 않는다는 에러 메세지를 띄우도록 했다.
그리고 상품을 장바구니에 담을때 상품 따로 옵션 따로 담는게 아니라 해당 상품의 해당 옵션제품을 담는거니까, 장바구니 버튼을 누르면 product_option_id를 백엔드에 다시 넘겨줘야 하기 때문에 상세페이지에서 각 옵션별 product_option_id정보도 같이 줬다. 상품id와 옵션id만 있어도 장바구니 기능에서 해당 제품 id를 찾아서 담을 수도 있지만 상세페이지에서 옵션별 재고를 보여주는 쇼핑몰도 있어서 나중에 재고관리 기능까지 추가되면 그부분을 활용할 수도 있을 것 같아서 상세페이지에서 해당상품의 해당옵션 아이디와 재고수량도 리턴해서 줬다.
class ProductDetailView(View):
def get(self, request, product_id):
try:
product = Product.objects.get(id=product_id)
images = product.productimage_set.all()
options = product.options.all()
result = {
'id' : product.id,
'name' : product.name,
'price' : product.price,
'is_green': product.is_green,
'is_best' : product.is_best,
'images' : [{
'id' : image.id,
'url': image.url
} for image in images],
'options' : [{
'option_id' : option.id,
'name' : option.name,
'product_option_id' : product.productoption_set.get(option_id=option.id).id,
'product_option_stock': product.productoption_set.get(option_id=option.id).stock
} for option in options]
}
return JsonResponse({'result': result}, status=200)
except Product.DoesNotExist:
return JsonResponse({'message': 'PRODUCT_DOES_NOT_EXIST'}, status=400)
3. URLconf
메인페이지의 엔드포인트는 /products/main이 되도록하고
상품 상세페이지는 /products/detail/<상품id> 경로로 요청할 수 있게 정의했다.
# products.urls.py
from django.urls import path
from products.views import MainPageView, ProductListView, ProductDetailView
urlpatterns = {
path('/main', MainPageView.as_view()),
path('/<int:category_id>', ProductListView.as_view()),
path('/detail/<int:product_id>', ProductDetailView.as_view()),
}
'wecode' 카테고리의 다른 글
구방문방구 | 상품목록 페이지네이션(offset, limit), 검색 (0) | 2022.07.30 |
---|---|
구방문방구 | 상품목록 정렬하기(query parameter) (0) | 2022.07.30 |
구방문방구 | 전체/카테고리별 상품리스트 api (0) | 2022.07.30 |
구방문방구 | 데이터베이스 모델링 (0) | 2022.07.24 |
[Mission 6] 로그인 JWT 발급 (0) | 2022.07.17 |