안녕하세요. 이번 시간에는 django에서 string 조건 검사를 할 때 쓸 수 잇는 contains, icontains, exact, iexact에 대해 간단하게 알아봅시다. 제대로 이해하시려면 collation에 대한 지식도 필요하고, 이 문서를 볼 필요도 있긴 합니다만, 추후에 조금 딥하게 다뤄보도록 하겠습니다. 

 


 

 먼저, 데이터는 이렇게 3개가 있습니다. "hi my name is cho", "nice to mEet you", "nice to meet you" 이렇게 세 개의 포스트가 있습니다.

 

 

 먼저, icontains는 대소문자 구분 없이 문자열에 "meet"가 들어가는 것을 뽑아줍니다. "m"이나 "M" 등은 아스키 범위 내에 들어가기 때문에, "mEet"가 걸리던, "meet"가 걸리던 match 되었다고 평가합니다. 문서를 보면, outside ascii와 ascii의 동작을 설명합니다.

 

 결과는 위와 같습니다.

 

 이제 contains를 써 봅시다. i가 빠졌으니, 대소문자 구분을 하지 않습니다. "meet"라는 것이 포함된 포스트를 찾는데요. 아까와는 다르게, 대소문자를 구분하게 됩니다.

 

 

 당연하게도 "mEet"가 들어간 포스트가 나오지 않게 됩니다.

 


 이제 iexact를 알아봅시다. 이것은, post의 내용이 "nice to meet you"와 같은지를 검사합니다. 그런데, 대소문자 구분을 하지 않습니다. 따라서, "nice to mEet you"와 "nice to meet you" 2개가 나올 겁니다. 정말로 그런지 볼까요?

 

 

 정말 그렇게 나오네요. 반면에 exact는, 대소문자를 구분합니다.

 

 

 해당 쿼리는 post의 내용이 "nice to meet you"인지를 검사합니다.

 

 

 하나만 나오게 되네요. 주의해야 할 점은, sqlite의 경우 contains가 icontains처럼 동작합니다. 이는 문서에도 나와 있는 부분인데요. 간단하게 테스트를 해 보겠습니다.

 

 

 하나는 대소문자 구분을, 하나는 구분을 하지 않습니다. 그렇기 때문에, 위의 결과는 1개가 나오고, 밑의 결과는 2개가 나와야 합니다. 그게 기댓값인데요. sqlite를 쓰는 경우, 그렇지 않습니다.

 

 

 똑같이 결과 2개가 나옴을 알 수 있어요. 주의해야 할 부분입니다.

 


 그러면, post에 "meet"이나 "cho"가 포함된 포스트는 어떻게 검색해야 할까요? sql로 치면 LIKE ~ or LIKE ~ 인 셈인데요. 조건절 2개가 연결이 된 셈입니다. 보통, 이럴 때 고려해 볼만한 것은 Q 개체입니다. 이를 이용해서 복잡한 조건절이 연결된 것들을 손쉽게 제너레이션 할 수 있어요. 동적 쿼리 작성할 때도 유용하게 이용됩니다.

 

 

 13번째 줄의 "meet"가 포함된 조건절 하나와, 14번째 줄의 "cho"가 포함된 조건절 하나를 Q.OR로 연결해 주었습니다. 그러면, q는 어떻게 되느냐. "meet"가 포함되거나, "cho"가 포함되거나가 되어 버립니다. 따라서, 15번째 줄에 Q를 넣어주면, 결국 "cho"가 post에 포함되던지, "meet"가 포함되던지. 이렇게 걸어버리게 됩니다.

 

 

 결과는 어떤가요? "cho"나 "meet"가 포함된 포스트 둘이 나오게 됩니다.