본문 바로가기
Python

Django ORM 활용하여 하이픈 제거하여 데이터 가져오기

by Shark_상어 2023. 8. 17.
728x90

from django.db.models.functions import Replace

class RemoveHyphen(Func):
    function = 'REPLACE'
    template = "%(function)s(%(expressions)s, '-', '')"

  1. class RemoveHyphen(Func):
    • RemoveHyphen는 Func 클래스를 상속하여 사용자 정의 함수를 생성하는 클래스입니다. 이 이름 아래에 정의된 로직을 사용하여 SQL 함수를 생성한다.
  2. function = 'REPLACE'
    • function 변수는 데이터베이스에서 사용될 SQL 함수의 이름을 저장합니다. 여기서는 MySQL의 REPLACE 함수를 사용하고 있습니다.
    • REPLACE 함수는 문자열에서 특정 부분 문자열을 다른 문자열로 대체할 때 사용한다.
  3. 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")


  1. annotate():
    • 이 메서드를 사용하여 Customer 모델의 각 행(row)에 대한 추가 계산 또는 변환을 수행한 결과를 새로운 필드로 추가한다.
    • Replace 함수는 첫 번째 인자로 지정된 필드의 문자열에서 두 번째 인자의 문자열을 세 번째 인자의 문자열로 바꾸는 역할을 한다. 여기서는 mom_phone, dad_phone, customer_homecall 필드에서 - (하이픈)을 제거하고 있다.
    • 결과적으로 새로운 필드들인 mom_phone_without_hyphen, dad_phone_without_hyphen, customer_homecall_without_hyphen가 생성되며, 이들 필드에는 하이픈이 제거된 전화번호 값이 저장된다.
  2. filter():
    • filter() 메서드를 사용하여 데이터베이스에서 특정 조건에 맞는 행들만 선택한다.
    • 여기서는 mom_phone, dad_phone, 그리고 하이픈을 제거한 새로운 필드들을 _str과 비교하여 해당 문자열이 포함된 행을 필터링하고 있다. (icontains는 대소문자를 구분하지 않는 부분 문자열 검색입니다.)
  3. distinct():
    • 중복된 결과를 제거하고, 유일한 행들만 선택한다.
  4. order_by("-id"):
    • 결과를 id 필드를 기준으로 내림차순으로 정렬한다.
  5. values():
    • 지정된 필드의 값들만 선택하여 딕셔너리 형태로 반환합니다. 이로 인해, 쿼리의 결과는 각 행에 대한 정보를 포함하는 딕셔너리의 리스트로 반환된다.

결론적으로, 이 코드는 Customer 모델에서 전화번호 필드와 하이픈이 제거된 새로운 전화번호 필드에 _str이 포함되는 행을 찾아서, 중복을 제거하고 id 필드를 기준으로 내림차순 정렬한 뒤, 지정된 필드의 정보만을 딕셔너리 형태로 가져오는 쿼리를 수행한다.

728x90