[Django, DRF] 장고 쿼리 필터 (query filter)

장고 ORM을 이용하여 DB에서 데이터를 불러올 때 내가 원하는 데이터만을 가져오게 하기 위해서는 필터를 사용해야 한다.

 

기본적으로 model이름.objects.all()을 할 경우 해당 테이블의 모든 데이터를 가져온다. 특정한 값만 가지고 오고 싶은 경우 이렇게 하면 상당히 비효율적이다. 이때 filter를 이용하여 원하는 값만 가져올 수 있다.

 

model이름.objects.filter()

이것을 이용하면 된다.

 

 

  • exact - 정확히 일치하는 데이터 가져오기
  • iexact - 대소문자 구분 없이 정확히 일치하는 데이터 가져오기

None을 찾는 것은 Null을 찾는 것과 동일하다.

model이름.objects.filter(id__exact=1)
model이름.objects.filter(id__exact=None)

 

 

  • contains - 포함하고 있는 문자열 찾기
  • icontains - 대소문자 구분 없이 포함하고 있는 문자열 찾기
model이름.objects.filter(title_contains='Korea')

 

 

  • gt - 부등호 greater 해당 값보다 큰 값들만 찾기
  • gte - 크거나 같은 값들만 찾기
  • lt - 작은 값들만 찾기
  • lte - 작거나 같은 값들만 찾기
model이름.objects.filter(id_gt=10)
SELECT ... WHERE id > 10;

 

  • range - 범위 (날짜만 되는건가.. 아직 모르겠음)
import datetime
start_date = datetime.date(2012, 1, 1)
end_date = datetime.date(2022, 3, 31)
model이름.objects.filter(pub_date__range=(start_date, end_date))

 

  • startswith - 접두사 포함하고 있는 값들 찾기
  • istartswith - 대소문자 구분 없이 접두사 포함하고 있는 값들 찾기
  • endswith - 접미사 포함하고 있는 값들 찾기
  • iendswith - 대소문자 구분 없이 접미사 포함하고 있는 값들 찾기

 

 

 

조건 여러 개 걸기

쿼리를 하다 보면, 조건이 하나가 아니라 여러 개를 걸고 싶을 경우가 존재한다. 생각보다 간단하다.

 

AND

 

아래 세 가지 방법 중 하나를 이용하면 된다.

queryset_1 = User.objects.filter(
    first_name__startswith='R',
    last_name__startswith='D'
)

queryset_2 = User.objects.filter(
    first_name__startswith='R'
) & User.objects.filter(
    last_name__startswith='D'
)

queryset_3 = User.objects.filter(
    Q(first_name__startswith='R') &
    Q(last_name__startswith='D')
)

 

 

더보기
In [10]: str(queryset_2.query)
Out[10]: 'SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE ("auth_user"."first_name"::text LIKE R% AND "auth_user"."last_name"::text LIKE D%)'

In [11]: str(queryset_1.query) == str(queryset_2.query) == str(queryset_3.query)
Out[11]: True

 

 

OR

 

아래 두 가지 방법 중 하나를 이용하면 된다.

queryset = User.objects.filter(
        first_name__startswith='R'
    ) | User.objects.filter(
    last_name__startswith='D'
)

from django.db.models import Q
qs = User.objects.filter(Q(first_name__startswith='R')|Q(last_name__startswith='D'))

 

 

NOT

 

아래 두가지 방법중 하나를 이용하면 된다.

queryset = User.objects.exclude(id__lt=5)


from django.db.models import Q
queryset = User.objects.filter(~Q(id__lt=5))

 

 


참고

https://django-orm-cookbook-ko.readthedocs.io/en/latest/index.html

https://gaussian37.github.io/python-django-django-query-set/