field lookup

공식문서

https://docs.djangoproject.com/en/3.0/ref/models/querysets/#id4

  • SQL의 WHERE에 해당되는 기능

  • QuerySet메소드인 filter(), exclude(), get()등에 키워드 인자로 지정

  • 어떤 lookup type에도 해당이 안 될 경우(Example.objects.get(id=1)) 자동적으로 exact로 적용

  • 사용법은 fieldname__lookuptype (Example.objects.get(id__exact=1)


exact

정확하게 일치하는 값을 검색.

None값을 넣게 되면 SQL의 IS NULL 구문을 사용하는 것과 같다.

# WHERE id = 14;
Entry.objects.get(id__exact=14) 
# WHERE id IS NULL;
Entry.objects.get(id__exact=None) 

iexact

대소문자의 구분없이 정확하게 일치하는 값을 검색.

None값을 넣게 되면 SQL의 IS NULL구문을 사용 하는 것과 같다.

# WHERE name ILIKE 'beatles blog';
Blog.objects.get(name__iexact='beatles blog')
# WHERE name IS NULL;
Blog.objects.get(name__iexact=None)

contains

대소문자를 구분하고 문자열을 포함하고 있는 것을 검색.

# WHERE headline LIKE '%Lennon%';
Entry.objects.get(headline__contains='Lennon')

icontains

대소문자를 구분하지 않고 문자열을 포함하고 있는 것을 검색.

# WHERE headline ILIKE '%Lennon%';
Entry.objects.get(headline__icontains='Lennon')

in

  • 주어진 iterable한 객체(리스트, 튜플, 쿼리셋)에 포함되어 있는지 검색.

    # WHERE id IN (1,3,4);
    Entry.objects.filter(id__in=[1,3,4])
  • 쿼리셋을 사용하여 동적으로도 검색이 가능하다.

    # WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE='%Cheddar%')
    inner_qs = Blog.objects.filter(name__contains='%Cheddar%')
    entries = Entry.objects.filter(blog__in=inner_qs)
  • values() 나 values_list()를 쓸 __in에 쓸 경우 결과 값은 하나의 필드만을 반환 해야 한다.

    inner_qs = Blog.objects.filter(name__contains='Ch').values('name')
    entries = Entry.objects.filter(blog__name__in=inner_qs)
  • 만약 두개의 필드로 반환하는 values()를 할 경우 TypeError를 raise를 시킬 것이다.

    # Bad code! Will raise a TypeError.
    inner_qs = Blog.objects.filter(name__contains='Ch').values('name', 'id')
    entries = Entry.objects.filter(blog__name__in=inner_qs)
  • 중첩된 쿼리를 사용 할 때는 데이터베이스의 성능 특성을 이해하고 써야 한다. 일부 데이터베이스의 경우 중첩 쿼리를 잘 처리 하지 못한다. 그래서 __in에 대한 list 목록을 미리 추출하여 두번째 쿼리에 해당 list를 사용 하는것이 더 좋다.

    values = Blog.objects.filter(name__contains='Cheddar').values_list('pk', flat=True)
    entries = Entry.objects.filter(blog__in=list(values))

    두번째 쿼리에서 list()를 사용하여 첫번째 쿼리를 강제로 실행. 중첩 쿼리를 실행하지 않게 한다. - in을 실행하면서 Entry를 계속 검색하는데 거기서 values 쿼리가 중복하여 실행된다. 그것을 방지.

gt, gte

  • gt : ~보다 큰.
  • gte : ~보다 크거나 같은.
    # WHERE id > 4;
    Entry.objects.filter(id__gt=4)
    # WHERE id >= 4;
    Entry.objects.filter(id__gte=4)

lt, lte

  • lt : ~보다 작은.
  • lte : ~보다 작거나 같은.
    # WHERE id < 4;
    Entry.objects.filter(id__lt=4)
    # WHERE id <= 4;
    Entry.objects.filter(id__lte=4)

startswith, istartswith

  • startswith : 대소문자를 구분하여 시작하는 문자열.
  • istartswith: 대소문자를 구분하지 않고 시작하는 문자열.
    # WHERE headline LIKE 'Lennon%';
    Entry.objects.filter(headline__startswith='Lennon')
    # WHERE headline ILIKE 'Lennon%';
    Entry.objects.filter(headline__istartswith='Lennon')

endswith, iendswith

  • endswith : 대소문자를 구분하여 끝나는 문자열.
  • iendswith: 대소문자를 구분하지 않고 끝나는 문자열.
    # WHERE headline LIKE '%Lennon';
    Entry.objects.filter(headline__endswith='Lennon')
    # WHERE headline ILIKE '%Lennon';
    Entry.objects.filter(headline__iendswith='Lennon')

range

  • 범위를 안에 있는지 검색.
    start_date = date(2005, 1, 1)
    end_date = date(2005, 3, 31)
    # WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
    Entry.objects.filter(pub_date__range(start_date, end_date))
  • SQL에서 BETWEEN을 날짜, 숫자, 문자에서 사용하는 것처럼 range도 사용 가능하다.
    날짜가 있는 DateTimeField를 필터링 하는 경우 마지막 날의 항목은 포함하지 않는다. 왜냐하면 주어진 날짜의 오전 0시로 경계가 설정되기 때문.
    WHERE pub_date BETWEEN '2005-01-01 00:00::00' and '2005-03-31 00:00:00';
  • 일반적으로 dates와 datetimes를 섞어쓰면 안된다.

date

  • datetime 필드의 경우 값을 날짜로 변환한다. 추가 체인이 가능하고, date값을 사용 한다.
    Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
    Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

year

  • date 및 datetime의 필드에서 년도가 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고 정수를 나타낸다.
    # WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
    Entry.objects.filter(pub_date__year=2005)
    # WHERE pub_date >= '2005-01-01';
    Entry.objects.filter(pub_date__year__gte=2005)

month

  • date 및 datetime의 필드에서 달이 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고 정수1 부터 12까지 나타낸다.
    # WHERE EXTRACT('month' FROM pub_date) = '12';
    Entry.objects.filter(pub_date__month=12)
    # WHERE EXTRACT('month' FROM pub_date) >= '6';
    Entry.objects.filter(pub_date__month__gte=6)

day

  • date 및 datetime의 필드에서 일이 정확히 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하고, 정수를 나타낸다.
    # WHERE EXTRACT('day' FORM pub_date) = '3';
    Entry.objects.filter(pub_date__day=3)
    # WHERE EXTRACT('day' FORM pub_date) >= '3';
    Entry.objects.filter(pub_date__day__gte=3)

week

  • date 및 datetime의 필드에서 ISO-8601의 기준에 따라 주 번호(1-52 또는 53)을 반환한다. 즉 월요일에 시작하는 주 및 첫번째 주는 목요일에 시작한다.
    Entry.objects.filter(pub_date__week=52)
    Entry.objects.filter(pub_date__week__gte=32, pub_date__week__lte=38)

week_day

  • date 및 datetime 필드에서 요일과 정확하게 일치 하는 것을 검색한다. 추가 체인 필드 검색이 가능하다. 정수1 부터 7까지 나타낸다.
    Entry.objects.filter(pub_date__week_day=2)
    Entry.objects.filter(pub_date__week_day__gte=2)
    연도와 월에 상관없이 1(일요일)과 7(토요일)사이에서 색인된다.

quarter

  • date 및 datetime 필드에서 분기가 정확하게 일치 하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 1년의 1/4인 1에서 4까지 나타낸다.
    # 2분기 검색
    Entry.objects.filter(pub_date__quarter=2)

time

  • datetime필드의 경우 값을 시간으로 변경하여 검색. 추가 체인 필드 검색이 가능하고, datetime.time값을 사용한다.
    Entry.objects.filter(pub_date__time=datetime.time(14, 30))
    Entry.objects.filter(pub_date__time__between=(datetime.time(8), datetime.time(17)))

hour

  • datetime 및 time 필드에서 시간이 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 23사이를 나타낸다.
    # WHERE EXTRACT('hour' FROM timestamp) = '23';
    Event.objects.filter(timestamp__hour23)
    # WHERE EXTRACT('hour' FROM time) = '5';
    Event.objects.filter(time_hour=5)
    # WHERE EXTRACT('hour' FROM timestamp) >= '12';
    Event.objects.filter(timestamp__hour__gte=12)

minute

  • datetime 및 time 필드에서 분이 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 59사이를 나타낸다.
    # WHERE EXTRACT('minute' FROM timestamp) = '29';
    Event.objects.filter(timestamp__minute=29)
    # WHERE EXTRACT('minute' FROM time) = '46';
    Event.objects.filter(time__minute=46)
    # WHERE EXTRACT('minute' FROM timestamp) >= '29';
    Event.objects.filter(timestamp__minute__gte=29)

second

  • datetime 및 time 필드에서 초가 정확하게 일치하는 것을 검색한다. 추가 체인 필드 검색이 가능하며, 0에서 59사이를 나타낸다.
    # WHERE EXTRACT('second' FROM timestamp) = '31';
    Event.objects.filter(timestamp__second=31)
    # WHERE EXTRACT('second' FROM time) = '2';
    Event.objects.filter(time__second=2)
    # WHERE EXTRACT('second' FROM timestamp) >= '31';
    Event.objects.filter(timestamp__second__gte=31)

isnull

  • IS NULL 과 IS NOT NULL에 대한 True, False값을 검색한다.
    # WHERE pub_date IS NULL;
    Entry.objects.filter(pub_date__isnull=True)

regex, iregex

  • regex : 대소문자를 구분하여 정규식을 검색.
  • iregex : 대소문자를 구분하지 않고 정규식을 검색.
    # WHERE title REGEXP '^(An?|The) +';
    Entry.objects.get(title__regex=r'^(An|The) +')
    # WHERE title REGEXP '(?i)^(an?|the) +'l;
    Entry.objects.get(title__iregex=r'^(an?|the) +'
    정규식을 전달하기 위해 r을 붙이는게 좋다.
728x90

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

[Django] gunicorn  (0) 2021.05.28
[Django] 배포를 위한 환경파일 분리  (0) 2021.05.28
[Django] decorator  (0) 2021.05.25
[Django] code formatting black 설치 및 적용  (0) 2021.05.20
[Django] 환경 변수 분리하기 django-environ  (0) 2021.05.18

+ Recent posts