from django.db.models.functions import Replace
class RemoveHyphen(Func):
function = 'REPLACE'
template = "%(function)s(%(expressions)s, '-', '')"
- class RemoveHyphen(Func):
- RemoveHyphen는 Func 클래스를 상속하여 사용자 정의 함수를 생성하는 클래스입니다. 이 이름 아래에 정의된 로직을 사용하여 SQL 함수를 생성한다.
- function = 'REPLACE'
- function 변수는 데이터베이스에서 사용될 SQL 함수의 이름을 저장합니다. 여기서는 MySQL의 REPLACE 함수를 사용하고 있습니다.
- REPLACE 함수는 문자열에서 특정 부분 문자열을 다른 문자열로 대체할 때 사용한다.
- template = "%(function)s(%(expressions)s, '-', '')"
- template 변수는 함수를 SQL 문으로 표현하는 방식을 지정한다.
- %(function)s는 function 변수의 값을 나타내며, 여기서는 'REPLACE'로 대체된다.
- %(expressions)s는 Func 클래스에서 처리하는 필드 또는 표현식을 나타냅니다. 예를 들면, mom_phone과 같은 필드명이 이 위치에 들어간다.
- template 내용에 따르면, SQL에서는 다음과 같은 형태로 생성된다: REPLACE(mom_phone, '-', '').
이 클래스는 RemoveHyphen('mom_phone', Value('-'), Value(''))와 같이 사용될 때, 해당 필드(mom_phone)의 값에서 하이픈(-)을 제거하는 SQL 문을 생성한다.
즉, RemoveHyphen 클래스는 Django ORM을 사용하여 데이터베이스 쿼리 시점에서 하이픈을 제거하는 작업을 수행하도록 한다.
ORM으로 적용
customer = Customer.objects.annotate(
mom_phone_without_hyphen=Replace('mom_phone', Value('-'), Value('')),
dad_phone_without_hyphen=Replace('dad_phone', Value('-'), Value('')),
customer_homecall_without_hyphen=Replace('customer_homecall', Value('-'), Value(''))
).filter( Q(mom_phone__icontains=_str) | Q(dad_phone__icontains=_str) | Q(mom_phone_without_hyphen__icontains=_str)
| Q(dad_phone_without_hyphen__icontains=_str) | Q(customer_homecall_without_hyphen__icontains=_str),
).distinct().order_by("-id").values(
"id", "customer_addr", "baby_name", "mom_name",
"mom_phone", "customer_type", "customer_visit1", "baby_birth", "baby_duedate")
- annotate():
- 이 메서드를 사용하여 Customer 모델의 각 행(row)에 대한 추가 계산 또는 변환을 수행한 결과를 새로운 필드로 추가한다.
- Replace 함수는 첫 번째 인자로 지정된 필드의 문자열에서 두 번째 인자의 문자열을 세 번째 인자의 문자열로 바꾸는 역할을 한다. 여기서는 mom_phone, dad_phone, customer_homecall 필드에서 - (하이픈)을 제거하고 있다.
- 결과적으로 새로운 필드들인 mom_phone_without_hyphen, dad_phone_without_hyphen, customer_homecall_without_hyphen가 생성되며, 이들 필드에는 하이픈이 제거된 전화번호 값이 저장된다.
- filter():
- filter() 메서드를 사용하여 데이터베이스에서 특정 조건에 맞는 행들만 선택한다.
- 여기서는 mom_phone, dad_phone, 그리고 하이픈을 제거한 새로운 필드들을 _str과 비교하여 해당 문자열이 포함된 행을 필터링하고 있다. (icontains는 대소문자를 구분하지 않는 부분 문자열 검색입니다.)
- distinct():
- 중복된 결과를 제거하고, 유일한 행들만 선택한다.
- order_by("-id"):
- 결과를 id 필드를 기준으로 내림차순으로 정렬한다.
- values():
- 지정된 필드의 값들만 선택하여 딕셔너리 형태로 반환합니다. 이로 인해, 쿼리의 결과는 각 행에 대한 정보를 포함하는 딕셔너리의 리스트로 반환된다.
결론적으로, 이 코드는 Customer 모델에서 전화번호 필드와 하이픈이 제거된 새로운 전화번호 필드에 _str이 포함되는 행을 찾아서, 중복을 제거하고 id 필드를 기준으로 내림차순 정렬한 뒤, 지정된 필드의 정보만을 딕셔너리 형태로 가져오는 쿼리를 수행한다.
'Python' 카테고리의 다른 글
Django modelserializer vs serializers.Serializer 차이 (0) | 2024.03.02 |
---|---|
RabbitMQ를 이용한 SMS 대량건 처리해보기 (0) | 2023.07.24 |
알리고 문자 서비스를 활용한 다수의 클라이언트 에게 MMS 메세지 보내기 (0) | 2023.06.26 |
AWS S3 이미지 파일 업로드 하기 (0) | 2023.06.20 |
AWS S3 이미지 파일 압축하여 다운로드 하기 (0) | 2023.06.20 |