import
Q 객체를 Django 내장모듈로 사용하려면 Import 해야함
from django.db.models import Q
AND 연산, OR 연산
## AND
# ex) first_name이 'a'로 시작하거나 last_name이 'b'로 시작하는 객체를 조회 (아래 두 코드는 동일하다)
User.objects.filter(Q(first_name__startswith='a') & Q(last_name__startswith='b'))
User.objects.filter(first_name__startswith='a', last_name__startswith='b')
## OR
# ex) first_name이 'a'로 시작하거나 last_name이 'b'로 시작하는 객체를 조회
User.objects.filter(Q(first_name__startswith='a') | Q(last_name__startswith='b'))
>>> 사실 AND 연산은 filter()내에서 그냥 조건들을 , 로 연결하여 사용하는 것과 같다.
>>> 하지만 OR 연산은 위와 같이 Q객체와 | 를 사용하면 코드 길이를 줄이고 가독성도 높일 수 있다.
# ex) first_name이 'a'로 시작하는 것을 제외한 객체 조회
User.objects.filtera(~Q(first_name__startswith='a'))
User.objects.exclude(first_name__startswith='a')
>>> NOT 연산은 Q객체 앞에 ~를 사용하여 쓸 수 있다.
q = Q()
q.add(Q(age=30), q.OR)
q.add(Q(last_name='kim') | Q(last_name='lee'), q.AND)
q.add(~Q(first_name__startswith='a'), q.OR)
User.objects.filter(q)
>> 첫 번째 줄과 같이 빈 Q객체를 먼저 선언할 수 도 있다.
>> 첫 번째 Q객체를 선언한 이후에 .add()메소드로 여러 개의 Q객체를 연결시킬 수 있다.
>> .add()에서 두 번째 인자에 앞의 Q객체와 연결될 때 어떤 연산자로 연결할지를 써주면 된다.
>> 위 예시를 SQL로 작성하면 아래와 같다.
# 위와 동일한 결과
select *
from user
where age=30 and (first_name='kim' or first_name='lee') and last_name not like 'a%';