✓ products/meta
"category_list" : [
{
"category_name" : category.name,
"category_id" : category.id,
"category_description_title" : category.description_title if category.description_title else None,
"category_description" : category.description if category.description else None
} for category in menu.category_set.all()
]
- Point
- category에 따라서 description_title과 desciption이 없는 경우가 있으므로 if문을 사용해 해당 column값이 없을 때는 None으로 처리
- List comprehesion 적용
- _set.을 통해 역참조 데이터 불러오기
✓ products
menu_id = request.GET.get('menu_id', None)
category_id = request.GET.get('category_id', None)
skintype_ids = request.GET.getlist('skintype_id', None)
productfeature_ids = request.GET.getlist('productfeature_id', None)
ingredient_ids = request.GET.getlist('ingredient_id', None)
search_name = request.GET.get('search_name', None)
- Point
- Query parameter를 사용하여 상품 리스트를 보내줘야 하는 여러 가지 경우를 하나의 endpoint로 구현
- 필터링의 경우 .getlist를 이용하여 조건 별로 하나 이상의 값을 받을 수 있도록 함
q = Q()
q.add(Q(category__menu_id=menu_id), q.OR)
q.add(Q(category_id=category_id), q.OR)
q.add(Q(name__contains=search_name), q.OR)
products = Product.objects.filter(q)
if skintype_ids:
products = products.filter(Q(feature__in=skintype_ids)).distinct()
if productfeature_ids:
products = products.filter(Q(feature__in=productfeature_ids)).distinct()
if ingredient_ids:
products = products.filter(Q(ingredient__in=ingredient_ids)).distinct()
- Point
- Q 객체를 이용하여 Query parameter에 따라 조건에 맞는 products 정의 가능
- 해당하는 Query parameter가 없는 경우, None값으로 처리되어 결과로 빈 query set이 나옴. 이후 or로 묶어주면 요청받은 Qurey parameter의 값만 Product의 filter에 적용 가능
- 메뉴별 상품 리스트인지 카테고리별 상품 리스트인지가 결정된 이후의 products에 필터링 조건을 추가로 걸어주면 해당 환경에서 필터링 가능
- .getlist에서 list로 받아온 값을 Q 객체에 담아주면 or 연산자로 묶여서 처리되어 중복된 query가 생성되기 때문에 .distinct()를 적용
- Blocker
- 필터링 조건 3가지 중 2가지가 같은 column의 값이어서 효율적인 로직 구상에 어려움을 겪음
- filter를 여러번 돌리는 지금의 방법은 비효율적. 이 외에 다른 접근 방식을 찾아보려고 했으나 4일간 고민했보았음에도 프로젝트가 끝낼 때까지 다른 방향을 찾지 못해서 추가적으로 고민해봐야 함
✓ products/〈int:product_id〉
feature_result = [
{
"feature_category_name" : feature_category.name,
"features" : [feature.name for feature in feature_category.feature_set.filter(product=product)]
} for feature_category in set(FeatureCategory.objects.filter(feature__in=product.feature.all()))
]
- Point
- product와 feature는 다대다 관계로 묶여 있고, feature는 feature category를 정참조 하고 있음
- feature category는 product마다 다르기 때문에 feature category부터 찾은 다음 product로 필터링해서 feature값을 가져옴
✓ products/popular
COUNT_RANKING = 5
products = Product.objects.all().order_by('-count')[:COUNT_RANKING]
- Point
- 몇 순위까지 보여줄 것인지는 변동 가능성 있기 때문에 상수 처리
- .order_by를 이용해 제품 상세 데이터가 response 될 때마다 1씩 쌓이게 설정해둔 count값을 기준으로 Product를 정렬한 다음 상위 5가지 제품 리스트를 전송함