Framework/Django

장고 Q 사용 (Code Refactoring)

JM Lee 2023. 6. 23. 03:16
728x90

Q는 장고 model에서 제공하는 orm 중 하나로, DB filter 조건에 and / or문을 추가하고 싶을 때 사용한다.

 

그럼 그냥 where에 or 문 넣으면 되는 걸 왜 이렇게 어려운 용어로 필터링할까?

 

코드가 간편해지기 때문.

# 예시
from django.db.models import Q

    def get_queryset(self):
        search_key = self.request.GET.get("search", None)
        q = Q()
        if search_key:
            q = self.search(search_key)
        category_id = self.request.GET.get("category")

 

위의 코드를 Q를 쓰지 않고 리팩토링하면 어떻게 될까?

 

def get_queryset(self):
    search_key = self.request.GET.get("search")
    category_id = self.request.GET.get("category")

    if search_key:
        queryset = self.search(search_key)
    else:
        queryset = self.model.objects.all()

    if category_id:
        queryset = queryset.filter(category_id=category_id)

    return queryset

코드가 길면 길수록 Q의 효과는 뚜렷하게 나타난다.

 

 

이전에 공부해보았던 SQL과 비슷한 느낌이어서 이해가 좀 빨리 되었다.

#sql 쿼리문
select * from product where category=치즈 or sub_category=모짜렐라

# 장고 orm
Product.objects.filter(Q(category=치즈) | Q(sub_category=모짜렐라))

 

 

AND 조건 사용 예시는 다음과 같다.

Products.objects.filter(Q(name='backpakc') & Q(no=12312))

 

NOT 조건 사용 예시는 다음과 같다.

# 방법 비교
 
 # ex. (카테고리 = 한식) 조건을 만족하지 않는 모든 사용자
 1. exclude() # 일반적 사용
 >> queryset = User.objects.exclude(category='한식')

 2. filter(~Q()) # Q 사용
 >> from django.db.models import Q
 >> queryset = User.objects.filter(~Q(category='한식'))

 

다음과 같이 q.add를 사용하면 add 로 값을 추가할 때 처음 선언된 앞의 조건과 연결된다.

def search_ingredient_title_content(self):
        q = self.search_title_content()
        q.add(self.search_ingredient(), q.OR)
        return q

'Framework > Django' 카테고리의 다른 글

장고 50문 50답 채우기(1)  (0) 2023.07.14
대댓글 작성  (4) 2023.06.28
taggit 공식 문서 읽어보기  (0) 2023.06.21
Queryset method 정리  (1) 2023.06.20
시리얼라이저 오버라이딩  (0) 2023.06.19