당신은 멋쟁이, 우리는 장고쟁이~

0%

Django Models 15편 - 이미 정의된 모델 메서드 오버라이드 하기

Overriding predefined model methods


여러분들이 커스터마이즈 하고 싶은 데이터베이스의 동작을 캡슐화 해주는 모델 메서드들도 존재 합니다.


특히 우리는 종종 save()delete() 의 동작 방식을 바꾸고 싶어 집니다.


save() 나 delete() 같은 메서드들을 override 해서 동작 방식을 바꾸는것도 가능하고,

다른 어떤 모델 메서드들을 override 해서 사용하는것도 가능합니다.


내장된 메서드, save() 같은 메서드를 override 하여 사용하는 고전적인 예시는,


하나의 객체를 저장할때마다 다른 무언가를 발생시키고 싶을 때입니다.



Method override 예시


예시 코드를 둘러봅니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from django.db import models 


class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()

def save(self, *args, **kwargs):
do_something()
super().save(*args, **kwargs) # 실제 save() 를 호출
do_something_else()

# save()를 호출할때, do_something() 부분에 어떠한 작업을 하는 코드를 써주면,
# 실제 save() 가 동작하기 전에, do_something() 을 수행합니다
# 그리고, save()가 호출 되고 나서는, do_something_else() 부분에 있는 또다른
# 작업을 해줄수 있습니다.

def save(self, *args, **kwargs) 를 사용하여, 평범하게 객체를 저장하기 보다는, 다른 작업을 실행하고 저장할수 있는 기능을 가질수 있습니다.


저장하는것을 방지할수도 있습니다


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from django.db import models 


class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()

def save(self, *args, **kwargs):
if self.name == "Yoko One's blog":
return
# 블로그 이름이 "Yoko One's blog" 이면, save 가 호출 되지 않고
# 비어있는값이 return 됩니다
# "Yoko One's blog" 가 제목이 아닐경우, else 로 넘어갑니다.
else:
super().save(*args, **kwargs) # 실제 save()를 호출해서 save() 진행


super().save(*args, **kwargs)


처음에는 생소해 보일지 모르지만,


super().save(*args, **kwargs) 를 통해서,

superclass 의 메서드를 호출하는것이 중요합니다.

이것을 호출하여, 객체가 여전히 데이터베이스에 저장되게 하는것이 중요합니다.


superclass 메서드를 호출하지 않는다면, 기본적인 저장 동작이 일어나지 않을것이고.


이는 데이터베이스를 건들지 않습니다.


또한, 모델 메서드에 전달된 인자들을 전달하는것도 중요합니다.


*args, **kwargs 부분이 이 역할을 수행합니다.

Django 는 때때로, 내장 모델 메서드들의 능력을 확장하고, 새로운 인자들을 추가해줄수 있습니다.


정의된 모델안에서, *args**kwargs 를 사용하면,

인자들이 추가 되었을때, 코드가 자동으로 해당 인자들을 지원합니다.


Quick Note


override 된 모델 메서드들은, 대량으로 운영되는 상황에서는 호출되지 않습니다.


객체를 위한, delete() 메서드는 쿼리셋을 이용해서 대량으로 객체를 지울때에는 호출 되지 않습니다. 혹은, cascading delete 일때도 호출되지 않습니다.


사용자 정의 delete 로직의 실행을 확실시 하고 싶으면,

pre_delete 그리고/혹은 post_delete 신호를 사용합니다.


안타깝게도, 객체를 대량으로 creating 혹은 updating 하는 작업은 존재하지 않습니다.

save(), pre_save() 그리고 post_save() 들이 대량으로 작업해야 하는 상황에서는 호출되지 않기 때문입니다.