지난 포스팅에 이어, Django ORM에 대해 계속 얘기해 보겠습니다.
Django ORM 객체 전달과 Custom Template Tag 활용하기
Django ORM은 all(), filter(), get() 메소드와 return시 순서정렬을 목적으로 한 order_by()정도만 있어도, READ에 있어서는 거의 모든 요구사항을 충족시킬 수 있습니다.
먼저, 아래와 같은 model을 정의해서 DB 테이블을 하나 구성했다고 해보겠습니다.
class AdMon(models.Model):
ad_owner = models.CharField(max_length=255, null=True, blank=True, default="NPU", verbose_name="광고주")
ad_filename = models.CharField(max_length=255, null=True, blank=True, verbose_name="광고파일명")
clicks = models.IntegerField(default=0, verbose_name="누적클릭수")
start_date = models.DateTimeField(null=True, blank=True, verbose_name="게재시작일시")
expiry_date = models.DateTimeField(null=True, blank=True, verbose_name="게재만료일시")
class Meta:
verbose_name_plural = "광고컨텐츠 모니터링"
TradeNPU에서 실제 사용중인 모델을 많이 단순화 시켜서 끌어왔으며, 광고이미지 게재와 모니터링을 목적으로 한 테이블입니다.
이 테이블에 담긴 데이터를 READ함에 있어서 전체를 READ 하기 위해서는 아래와 같이 all() 메소드를 사용합니다.
ad_all = AdMon.objects.all()
여기서 전체를 한번 읽어들이는 과정을 ad_all 변수에 담는 과정을 이미 했기 때문에, 누적클릭수가 10회 이상 건들만 찾고자 한다면, 이후 코드라인에서는 AdMon을 다시 읽어들이는 과정이 필요 없이, 아래와 같이 코딩하면 filter() 메소드가 그대로 적용됩니다.
ad_filtered = ad_all.filter(clicks__gte=10)
이때, 누적클릭수 key에 대해 10이상인 값을 찾으려면 __gte 를 찾고자 하는 key값에 붙이고, 기준값을 10으로 설정합니다.
gte 는 'greater than or equal'을 의미합니다.
같은 식으로 이하값을 찾고자 한다면, lte 를 사용하며, 'less than or equal' 을 의미합니다.
이런 면은 pandas보다도 filtering이 간편하게 느껴지게 합니다.
ORM이 익숙치 않을 때엔, 당장 기능 생성이 급해서 pandas로 읽어 들여 코딩하던 때도 있었습니다.
지금은 리팩토링 진행하면서 pandas 개입되었던 부분들을 거의 다 없앴지만, ORM이 익숙치 않다면 pandas를 우회책으로 쓰는 방법도 있으니, 일단 너무 어렵게 받아들이지 마시고, ORM을 차근히 익혀 나가면 됩니다.
그러다 보면 filtering 하기 위해 ORM이 제공하는 메소드가 너무나도 간편한 부분이 많다는 부분을 깨닫게 됩니다.
우리가 공식문서를 항상 잘 살펴보아야 하는 이유이기도 합니다.
필자는 DB값이 필요한 function을 만들 때면, 가장 포괄되는 수준의 결과가 필터링된 객체를 우선 하나 만들곤 합니다. all()메소드를 써서, 전체를 긁어오거나, 최소한의 parameter만 던져주어 해당 기능에서 타겟하고 있는 값을 모두 포괄하고 있는 객체를 만들기 위한 filter()를 써서 변수 하나에 일단 담고 시작합니다.
이후 해당 객체에 대해 filer()와 get()등 필요한 필터링을 추가로 수행하는데, 이마저도 함수 정의 과정에서는 최대한 지양하고 있습니다. 왜냐하면, Custom template tag에 의한 filtering용 함수공통화 과정을 적극적으로 사용하기 때문입니다.
아래 코드는 tag_library에 등록하는 Custom template tag의 예제 입니다.
@register.filter
def owner_filter(ads, name):
return ads.filter(ad_owner=name)
우선, ads 에 해당되는 위치에 앞서, filtering을 한 번 진행한 ad_filtered 객체값이 첫번째 parameter로 오게 합니다.
그러면, 누적클릭수가 10회 이상인 객체값들 중에서 이 custom tag를 통해서 두번째, parameter name으로 광고주의 이름을 제공하면, ad_filtered 객체에서 다시 광고주 이름이 두번째 parameter로 받은 값과 일치하는 값을 filtering하여, orm 객체를 return하도록 짜여진 것입니다.
즉, 추가적인 narrow-down을 custom filter를 통해 얼마든지 짜낼 수 있다는 장점이 있습니다.
그리고, 한번 구성한 이러한 형태의 filtering은 다른 함수를 만들 때에도 얼만든지 또 사용해야할 필요가 있습니다. 그런데, 이를 각 함수 정의때마다 개별적으로 inner function으로 다시 정의하면 코드 재활용을 잘 하지 못하는 것이 됩니다.
custom tag는 코드를 재활용하기에 매우 적합한 역할을 하게 됩니다.
필자도 애초에는 그 쓰임새를 잘 몰라서, back-end에 중복된 filtering 코드들을 많이 사용했었습니다.
하지만, 위 내용을 깨닫고 난 이후 리팩토링 과정을 거치면서 공통적으로 요구되는 filtering코드들은 front-end custom template tag쪽으로 쫓아냈고, 이를 통해, back-end 코드의 가독성이 굉장히 개선되는 효과를 얻었습니다.
뿐만 아니라, 향후 function 작성에서도 간결한 코드를 유지하기도 좋아서 위 방식을 적극적으로 활용해야 한다고 강조하고 싶습니다.
그렇다면, front-end에서는 위 custom tag를 어떤식으로 표현할까요?
아래 코드를 참조해 주세요.
<td class="text-center pe-0" data-order="rating-4">
<span>{{ ads|owner_filter:"SAMSUNG" }}</span>
</td>
앞선, custom template tag 에서 함수 owner_filter를 정의했습니다.
이때, | 앞에 해당 함수에 던져줄 첫번째 paramter값을 줍니다. 그리고. function명을 지나 : 뒤에 두번째 parameter값을 주도록 합니다.
그러면, 해당 custom tag가 해당하는 값을 return합니다.
함수명과 변수명을 특정한 기능용으로 설정해서 그렇지, 어떠한 방법이든 위와 같이, 특정 값을 추가 filtering하는 동작이 필요한 경우에는 이 custom tag가 범용적으로 사용될 수 있습니다.
예제로, filter()메소드를 쓰는 경우를 들었지만, 이뿐만 아니라, 복잡한 연산과정이 필요한 상황도 custom tag 등록 때, 함수상에 코딩하면 Data Manipulation을 손쉽게 진행할 수 있겠습니다.
이제, ORM READ관련 내용은 어느 정도 훓었으니, 다음 포스팅에서 ORM UPDATE, CREATE 쪽으로 기술내용을 옮겨 보도록 하겠습니다.
NPU(엔피유) 관세사무소
대표관세사 고장주
Tel) 031-986-7190
E-mail) sales@npucus.com
[NPU관세사무소 홈페이지] https://www.npucus.com/
[NPU관세사무소 프로모션 페이지] https://www.tradenpu.com/npu_cus/
[무역비지니스 인텔리전스 서비스 | TradeNPU] https://www.tradenpu.com
[파이썬 실용 예제. 무역과 공공데이터] https://pdatinmylife.tistory.com
Certified Customs Broker JangJu Goh
Executive Customs Broker @ NPU Customs Consulting
CEO @ JG TradePlus
sales@npucus.com
Trade Compliance / Customs clearance management at foreign company
Working experience of Air export freight forwarding
Data Visualization / Independent development of business automation application – copyright of JGPO_Manager, JG Data Center, AutoCC and etc.
B2B consignment & direct export/import, B2C Overseas Buying Office consulting
Alibaba.com B2B trade / taobao B2C trade / Amazon.com global selling etc. Online trade regulation consulting.
Import license / Quarantine
English communication available
[TradeNPU for partnership proposal - JGTP] https://www.tradenpu.com/jgtp/
'파이썬(Python) > TradeNPU' 카테고리의 다른 글
관세청 Open API 활용 프로젝트 #1 화물통관진행정보조회하기 (1) (4) | 2024.11.12 |
---|---|
회원사 Item Introduction page 만들기 시리즈 V - ORM (1) (2) | 2024.11.11 |
회원사 Item Introduction page 만들기 시리즈 IV - Django Templates (5) | 2024.11.08 |
회원사 Item Introduction page 만들기 시리즈 III - Django Template Tags (2) | 2024.11.07 |
회원사 Item Introduction page 만들기 시리즈 II - 로그인 구현 (5) | 2024.11.05 |