ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • filter() - fields loopkups(**kwargs), Q objects(**args)
    Backend/Django 2023. 12. 3. 17:12

     

    Clone Coding을 하다가 생각없이 사용 중이던 filter() 함수의 사용법을 좀 더 깊게 파보고자 공식 문서를 살펴 보았다.


     

    filter()

    https://docs.djangoproject.com/en/4.2/ref/models/querysets/#filter

    QuerySet의 Member method 로 lookup parameter를 충족하는 객체들만 모아 새로운 QuerySet 을 생성하여 반환한다.

    즉 DB에서 특정 조건(lookup parameter)들로 조회하여 나온 결과를 다시 Model Instance로 생성하여 QuerySet에 담아 반환한다고 볼 수 있다.

     

    조건을 지정하는 방식으로는 field lookups(kwargs에 대입) 와Q object(args에 대입) 가 있다.

    여러 조건을 복잡하게 조합할 때(ex. OR, NOR)에는 Q object를 사용하는 것이 더 적합하다.

    Field lookups와 Q object롤 동시에 사용할 때에는 반드시 Q object가 Field lookups 보다 앞에 위치해야 한다. ( Python 문법을 따른다고 보면 된다. 함수 Parameter로 *args는 항상 **kwars보다 선언되어야 하므로)

     

     

    그럼 field lookups 란?

    더보기

    https://docs.djangoproject.com/en/4.2/ref/models/querysets/#field-lookups

     

    SQL의 WHERE 절에 사용될 조건들을 어 떤 방식으로 구체화할 것이지 결정하는 규칙이다. QuereSet의 filter(), get(), exclude() 등의 함수에서 lookup parameter(**kwargs) 에 사용된다.

     

    QuerySet을 검색할 때 사용할 Field 명 뒤에 double-underscore(__)로 연결한 field lookups를 사용한다.

    ex) QuerySetObj.objects.filter(id__exact=1)

    lookup parameter에 별도의 field lookups가 지정되지 않을 경우 100% 일치를 의미하는 exact 가 default로 사용된다.

     

    한 번에 여러 개의 field_lookups를 사용하는 것도 가능하다. 이 경우 모든 조건은 SQL문으로 치환 시  AND 연산으로 묶이는 효과를 보게된다.

    QuerySetObj.objects.filter(id__exact=1, name__startswith="Kim")

    => SELECT * FROM Table WHERE id==1 AND name LIKE "Kim%" 정도로 치환될 수 있다.

     

    exact(100% 일치), iexact(대소문자 무시), startswith(주어진 keyword로 시작), endwith (주어진 keyword로 끝) 등등의 규칙이 존재한다.(더 많은 종류는 위 Link에서 확인 가능)

     

    Django에서 기본 제공하는 규칙 외에도 custom lookups를 만들어 사용이 가능하다. (사용 해본 적 X, 아래 Link 참고)

    https://docs.djangoproject.com/en/4.2/howto/custom-lookups/

     

     

    더 복잡한 조건을 사용하고 싶을 땐 Q objects

    더보기

    이름에서 알 수 있듯 Q object는 SQL의 조건을 나타내는 '객체'이다.

    객체의 형태로 존재하므로 재사용이 가능하다.

    Q object 생성 시 생성자는 kwargs를 받는데 이때 전달 받는 값들은 Field lookups 를 따른다.

     

    &, |, ^ 와 같은 연산자로 연결될 수 있다.

    Q(question__startswith="who) | Q(question_starswith="what")

    이 경우 내부적으로는 두 개의 조건을 갖는 하나의 Q object가 생성되어 전달된다.

     

    Lookup 함수에서 쉼표(',') 로 두 개 이상의 Q object가 연결될 때에는  AND 연산으로 연결된다.

    QuerySet.objects.filter(Q(question__startswith='who'), Q(pub_date=(date(2023.12.14)))

    -> SELECT * FROM table WHERE question LIKE 'who%' AND pub_date="2023-12-14" 정도로 치환 될 수 있다.

     


    DB 공부를 할 때 LIKE 연산은 DB에 부하를 많이 주기 때문에 사용을 남발하면 안 된다고 배웠다. 

    그렇다면 Field lookups를 사용할 때에도 LIKE로 치환 될 것으로 예상되는 규칙들도 DB에 똑같이 부하를 많이 주게 되는 것일까?

    아니면 Django에서 내부적으로 어떤 처리를 하여 실제 SQL문에서 LIKE 연산을 사용하는 것 보다는 DB 부하가 덜한 것일까?

    이 점은 따로 조사가 필요하겠다.

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

    VS Code에서 Django Debug 설정  (0) 2023.10.15
    PyCharm에서 Django 디버그 모드 활성화하기  (0) 2023.10.10
    class Meta  (2) 2023.09.18
    django 입문(5) Model 3) DB에 Table 생성  (0) 2023.09.17
    django 입문(5) Model 2) 추가 기능  (0) 2023.09.17

    댓글

Designed by Tistory.