1차 프로젝트에서 ProductListView를 짜면서 가격순 정렬을 Restful API로 가져오는 코드를 짰었다.
당시 코드는 if 조건문을 사용하여 get으로 요청 받은 api가 일치 할 때 order_by로 정렬된 상품을 나열해주는 방식을 사용했다. 받아야할 api 주소가 달라지기 때문에 달라지는 조건(혹은 경우)에 따라 값을 전달해주면 된다고 생각을 했고, 아래와 같은 logic을 구현했다.
class ProductListView(View):
def get(self,request):
try:
sorted_products = request.GET.get('sort')
if sorted_products == 'price_low_high':
specified_products = Product.objects.order_by('product_price')
elif sorted_products == 'price_high_low':
specified_products = Product.objects.order_by('-product_price')
else:
specified_products = Product.objects.all()
product_list = [
{
'id' : specified_product.id,
'product_title' : specified_product.product_title,
'product_details' : specified_product.product_details,
'product_price' : specified_product.product_price,
'thumbnail_url' : specified_product.thumbnail_set.first().thumbnail_url
}
for specified_product in specified_products]
return JsonResponse({"mice_list":product_list}, status = 200)
except ValueError:
return JsonResponse({"message":'INVALID_LIST'}, status = 400)
그러나 이 코드의 문제점은 새로운 조건이 생겨날 때마다 sorting을 하여 if문이 계속 늘어난다는 점이었다. 해당 문제점을 위코드 멘토님께서 지적해주셔서 refactoring을 진행했다.
sorting_condition = {'price_low_high':'product_price', 'price_high_low':'-product_price'}
처럼 딕셔너리를 선언할 경우 더 많은 조건이 생길때, if문 없이 딕셔너리에 키값만 추가해도 확장성이 증가한다는 조언을 통해 딕셔너리를 어떻게 구현할지 고민했다.
딕셔너리에 대해서 다시한번 공부하면서 키 값과 벨류 값을 적절하게 가져와 사용할 방법을 생각했다.
그래서 구현한 코드는 아래와 같다.
우선 sorting_condition을 딕셔너리로 선언해주고, for 반복문으로 키값을 가져온다.
키 값이 api에서 요청해주는 값과 같을 경우 키 값에 해당하는 벨류 값을 order_by로 정렬된 값을 반환한다.
기존 if 조건문을 사용할 때보다 코드는 더욱 간단해졌고, 확장성은 늘어났다.
앞으로 상품 리스트 필터 기능을 사용할 때 큰 도움이 될것 같고, 이번 리팩토링을 통해 잘 동작이 되는 코드도 다시 보고 새롭게 구현해보는 일이 얼마나 중요한지 느끼게 되었다.
class ProductListView(View):
def get(self,request):
try:
sorted_products = request.GET.get('sort')
specified_products = Product.objects.all()
sorting_condition = {'price_low_high':'product_price', 'price_high_low':'-product_price'}
for condition in sorting_condition.keys():
if condition == sorted_products:
specified_products = Product.objects.order_by(sorting_condition.get(condition))
product_list = [
{
'id' : specified_product.id,
'product_title' : specified_product.product_title,
'product_details' : specified_product.product_details,
'product_price' : specified_product.product_price,
'thumbnail_url' : specified_product.thumbnail_set.first().thumbnail_url
}
for specified_product in specified_products]
return JsonResponse({"mice_list":product_list}, status = 200)
except ValueError:
return JsonResponse({"message":'INVALID_LIST'}, status = 400)