아래는 쇼핑몰의 제품 목록을 조회하는 장고 View 코드인데, 처음엔 정렬 조건을 정해주는걸 if문으로 하면 되겠다고 생각했다.
class ProductListView(View):
def get(self, request):
try:
category = request.GET.get('category')
search = request.GET.get('search')
sort = request.GET.get('sort', 'name')
offset = int(request.GET.get('offset', 0))
limit = int(request.GET.get('limit', 6))
#신상품순
if sort == "new":
sort = "-created_at"
#제품명순(가나다순)
if sort == "name":
"name"
#가격순
if sort == "price":
sort = "options__price"
if sort == ...
...
Product.objects.all().order_by(sort)
...
그러나 내가 보기에도 계속되는 if문은 줄일 수 있어 보였고 멘토님께 문의해보니 딕셔너리를 활용할 수 있다고 하셔서 다음과 같이 리팩토링 했다.
...
sort_set = {
"name" : "name",
"-name" : "-name",
"old" : "created_at",
"new" : "-created_at",
"price" : "options__price",
"-price": "-options__price",
"review": "-review_count",
"sales" : "-sales_sum",
}
sort = sort_set.get(sort, "name")
...
위에서 sort라는 쿼리파라미터 값을 받아서 sort_set 딕셔너리에 있으면 해당하는 값으로 변환되는 코드다.
딕셔너리명.get() 메서드는 찾는 key값이 없으면 None을 반환하는데, None 말고 다른 반환하는 값을 지정해줄 수 있다. 위와 같이 만들면 정렬 조건에 없는 값이 입력될 경우 이름순으로 정렬되게 된다.
:=
walrus operator를 활용하면 if문까지 합쳐서 줄일수도 있다.
파이썬에서는 열거형 데이터를 사용하기 위해 기본 Enum 모듈을 사용할 수 있다.
임포트문은 다음과 같다.
from enum import Enum
Enum은 다양하게 활용할 수 있는데 프로젝트를 하면서 장고 View에서 적용할 수 있는 부분이라면,
쇼핑몰 같은 경우 상품옵션이나 주문상태와 같이 열거할 수 있는 형태로 정의하는 것들에 유용하다.
예를 들어 배송이 완료된 주문만 필터링하기 위한 다음과 같은 코드가 있다.
Order.objects.filter(status_id=3)
나는 물론 status_id 3번이 배송완료를 의미하는건줄 알기 때문에 문제가 없지만 다른 사람이 본다면 3번의 의미를 알기 위해 DB에 들어가서 확인해봐야 하므로 불편하고 알아보기 힘들다. 이런 경우 Enum을 사용하는것이 유용하다.
...
class OrderStatusEnum(Enum):
PAID = 1
SHIPPED = 2
DELIVERED = 3
...
Order.objects.filter(status=OrderStatusEnum.DELIVERED.value)
Enum 상속클래스인 OrderStatusEnum에서 모든 주문상태(결제완료, 배송중, 배송완료)에 대한 값을 모두 지정해줬기 때문에 배송완료된 주문을 찾는 값을 단순히 status_id=3으로 하는것보다 좀 더 분명하게 나타낼 수 있다.
이렇듯 어떤 정해진 상태의 집합에 대하여 처리를 해줄 때는 Enum 클래스를 사용하면 좋다.
특정 상태를 하나의 집합으로 만들어 관리함으로써 코드를 정리하는데 수월합니다. 즉, 가독성이 높아지고 문서화를 하는데 도움이 됩니다.
출처: https://greendreamtrre.tistory.com/358