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

0%

Django Models 20편 - Model 상속 (Proxy models - 1)

Model 상속 (Proxy models)


Proxy models


Multi-table 상속을 사용할때에는, 새로운 데이터베이스 테이블이 각 서브 클래스 마다 생성 됩니다.


이는 보통 우리가 의도하는 동작이고, 서브 클래스들은, 베이스 클래스에 존재하지 않는 추가적인 데이터 필드들을 저장하기 위한 공간이 필요합니다.

하지만, 때때로 모델의 파이썬 동작을 바꾸고 싶을때가 있습니다 - 기본 메니저를 변경하거나 혹은 새로운 메서드를 추가할때 처럼 말이죠.

이것이 바로 프록시 모델 상속이 존재하는 이유 입니다. 기존 모델을 위해서 새로운 proxy 를 생성하는것 입니다.


모델의 파이썬 동작을 바꾸고 싶을때, 기존 모델을 위한 새로운 proxy 를 생성 합니다.

예) 기본 메니져 변경, 새로운 메서드 추가 등등


프록시 (proxy) 라는 개념은 영문으로 직역하면, 일종의 대리권, 대리인 이라 생각하면 되고.

일종의 부모 클래스의 복제품이라고 생각하면 됩니다.

다만, 부모 클래스와 동일한 데이터베이스 테이블을 사용합니다.


여러분들은 프록시 모델의 인스턴스들을 생성, 삭제, 그리고 업데이트를 해줄수 있고.


모든 데이터들은 마치 기존 모델을 사용하느것처럼 저장될수 있습니다.

차이점은, 여러분들이 proxy 의 기본 모델 정렬 혹은 기본 메니져 같은 것들을 뭔본 모델을 바꿀 필요 없이 수정할수 있다는 점 입니다.

프록시 모델은 일반 모델처럼 생성 됩니다

하지만, proxy 속성 값을 Meta 클래스 안에서, True 로 지정해주어야 합니다 .


아래 코드를 예시로 들면,


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

class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)

class MyPerson(Person):
# Meta 클래스 안에, proxy = True 로 설정해줌
class Meta:
proxy = True

def do_something(self):
# ...
pass

MyPerson 클래스는, 부모 클래스인 Person 클래스와 같은 데이터베이스 테이블에서 동작 합니다.


특히, Person 의 어떤 새로운 인스턴스들도 MyPerson 을 통해서 접근이 가능합니다. MyPerson 의 새로운 인스턴스들도 Person 을 통해서 접근이 가능합니다.


1
2
3
4
5
6
In [1]: p = Person.objects.create(first_name="Colin", last_name="Firth")                                                                                                  
In [2]: MyPerson.objects.get(first_name="Colin")
Out[2]: <MyPerson: MyPerson object (1)>

In [3]: Person.objects.get(first_name="Colin")
Out[3]: <Person: Person object (1)>

1
2
3
4
class OrderPerson(Person):
class MEta:
ordering = ["last_name"]
proxy = True

일반적인 Person 쿼리들은 정렬이 되지 않겠지만,


OrderedPerson 쿼리들은 last_name 기준으로 정렬이 될겁니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
In [4]: a = Person.objects.create(first_name="동원", last_name="강")                                                                                                      

In [5]: b = Person.objects.create(first_name="지석", last_name="강")

In [6]: c = Person.objects.create(first_name="문희", last_name="나")

In [7]: d = Person.objects.create(first_name="민영", last_name="박")

In [8]: e = Person.objects.create(first_name="태현", last_name="차")

In [9]: f = Person.objects.create(first_name="성경", last_name="이")

In [10]: Person.objects.all()
Out[10]: <QuerySet [<Person: Firth>, <Person: 강>, <Person: 강>,
<Person: 나>, <Person: 박>, <Person: 차>, <Person: 이>]>

# last_name 즉 성씨를 기준으로 정렬
In [11]: OrderedPerson.objects.all()
Out[11]: <QuerySet [<OrderedPerson: Firth>, <OrderedPerson: 강>, <OrderedPerson: 강>,
<OrderedPerson: 나>, <OrderedPerson: 박>, <OrderedPerson: 이>, <OrderedPerson: 차>]>

프록시 모델들은, Meta 속성을 일반 모델들이 상속 받는 방식과 동일하게 상속 받습니다.