될때까지

((TURTLE HOME)) 8일차 : ProductListView ordering refactoring 본문

프로젝트/wecode1차 : TURTLE-HOME

((TURTLE HOME)) 8일차 : ProductListView ordering refactoring

랖니 2022. 7. 27. 09:05
728x90

어제까지 작성했던 코드는 아래와 같다.

class ProductListView(View):
    def get(self, request):
        
        sort_condition = request.GET.get('sort-by')   
        
        products = Product.objects.all()   
            
        result = [{ 'id'       : product.id, 
                    'name'     : product.name,
                    'image_url': product.image_url,
                    'prices'   : 
                        [int(p.price) for p in product.productoption_set.filter(product_id = product.id)]
                    } for product in products] 
        
        if sort_condition == 'price':
                    
            result = sorted(result, key = lambda x : x['prices'][0])
        
        elif sort_condition == '-price':
        
            result = sorted(result, key = lambda x : x['prices'][0], reverse=True)
    
        elif sort_condition == '-id':
            
            result = sorted(result, key = lambda x : x['id'], reverse=True)
        
        return JsonResponse({'result':result}, status=200)

키야 중복되던 코드도 줄였고, 딕셔너리의 키값을 사용해서 정렬도 했고. 진짜 잘했다 기억에 남는 코드가 되겠다 싶었는데 멘토님의 리뷰를 보고 멘탈이 우당탕탕.. 나갔다지 ^_^

정렬 구현 방법이 현재는 DB에서 모든 데이터를 가져온 뒤에 파이썬에서 정렬하고 있습니다. 해당 방법이 아닌 애초에 DB에서 가져올 때 정렬된 데이터를 가져올 수 있습니다. 또한 해당 방법을 적용 할 때 여러 정렬 조건에 대해 if가 아닌 dictionary를 활용해서 한 번 구현해 보세요.

그렇다. 현재 내 코드는

products = Product.objects.all()  로 DB에서 모든 데이터를 가져왔고,

result = [{'키' : '벨류' , '키2:', '벨류2'..} for product in products]  가져온 데이터들의 정보를 객체로 변경 후 해당 컬럼값을 사용했다.

result = sorted(result, key = lambda x : x['prices'][0], reverse=True) 를 사용해서 정렬을 했다.

이렇게 하지 않고 애초에 DB에서 정렬된 데이터를 가져올 수 있는데, order_by를 사용하면 된다.

 

1차 수정

class ProductListView(View):
    def get(self, request):
        
        sort_condition = request.GET.get('sort-by')
        
        if sort_condition == 'price' :
            products = Product.objects.order_by('price')
        
        elif sort_condition == '-price' :
            products = Product.objects.order_by('price')
            
        elif sort_condition == '-id':
            products = Product.objects.order_by('-created_at')
        
        result = [{ 'id'       : product.id, 
                    'name'     : product.name,
                    'image_url': product.image_url,
                    'prices'   : 
                        [int(p.price) for p in product.productoption_set.filter(product_id = product.id)] 
                    } for product in products]  
        
        return JsonResponse({'result':result}, status=200)

Django에서 order_by 메소드를 사용하면 쿼리셋을 정렬하여 가져올 수 있다. 괄호안의 값을 -붙이면 내림차순으로 정렬이 된다! 

 

2차 수정

이때 중복되는 if조건들을 딕셔너리로 바꾸는 방법은 아래와 같다. 클라이언트(프론트)로부터 받는 값의 이름을 딕셔너리 왼쪽에 써주고, 해당 값일 때 정렬주고 싶은 순서를 오른쪽에 작성한다. 딕셔너리.get()은 괄호안의 값이 키가 되어, 해당 키에 대한 벨류값을 반환하고 없으면 None을 기본값으로 준다. 여기서는 없을 경우 created_at을 사용하여 정렬하게끔 손을 써뒀다.

class ProductListView(View):
    def get(self, request):
        
        sort_condition = request.GET.get('sort-by')
        
        sort_condition_dict = {
            'low_price' : 'price',
            'high_price' : '-price',
            'newest' : '-created_at'
        }
        
        sort_by_value = sort_condition_dict.get(sort_condition, 'created_at')
        
        products = Product.objects.order_by(sort_by_value)
        
        result = [{ 'id'       : product.id, 
                    'name'     : product.name,
                    'image_url': product.image_url,
                    'prices'   : 
                        [int(p.price) for p in product.productoption_set.filter(product_id = product.id)] 
                    } for product in products]  
        
        return JsonResponse({'result':result}, status=200)

 

 if조건문의 연속을 딕셔너리를 사용해서 바꾸는 방법을 배웠고, order_by에 대해서 알게되었다!!! 

728x90