Django models | proxy

Jihun Kim·2021년 12월 30일
0

Django

목록 보기
5/8
post-thumbnail
post-custom-banner

Proxy model

Multi-table inheritance에 의하면 부모 객체를 상속 받아 자식 객체를 생성할 수 있는데, 이 때 자식 객체는 subclass가 된다. 그러면 subclass는 부모 객체에는 없는 추가적인 데이터를 저장하는 용도로 사용할 수 있다.

혹은 부모 객체의 python behavior(default manager 변경 등)만 변경하거나 새로운 메소드를 추가해 사용할 수도 있는데 이 때 Proxy model을 사용할 수 있다. 즉, 원래 모델에 대한 ‘proxy’를 생성하여 proxy 모델 instances의 데이터에 대해 create, delete, update를 할 수 있으며 모든 데이터는 원본 데이터를 사용하는 것처럼 저장된다. proxy model을 이용해 원본 데이터에 영향을 주지 않고 default model의 ordering을 변경시키거나 default manager를 변경시킬 수 있다. 이 기능을 사용하려면 “Meta class”에 proxy=True를 지정하기만 하면 된다.

from django.db import models

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

class OrderedPerson(Person):
    class Meta:
    	ordering = ["last_name"]
        proxy = True

    def do_something(self):
        # ...
        pass

→ 이와 같이 proxy 모델을 정의하면 Person 쿼리는 정렬되지 않는 반면 OrderedPerson 쿼리는 “last_name”을 기준으로 정렬된 상태로 존재하게 된다.



Proxy model이 왜 필요할까?

만약 원본 모델을 대리하여 사용할 모델이 필요한데 원본 모델과 똑같은 필드가 전부 필요하지 않다면 unmanaged model을 쓰는 것이 맞다. 그러려면 Meta.managed=False를 적기만 하면 된다.

그러나 이렇게 하면 새로운 모델에 또다시 반복작업을 해야 하며 원본 모델에 변화 내역이 있는 경우 proxy model에도 똑같이 싱크를 맞춰줘야 한다는 불편함이 생긴다. proxy model은 원본 모델과 똑같은 기능을 하기 때문에 부모 모델을 상속 받을 경우 부모 모델의 모든 필드와 managers 역시 똑같이 상속 받게 된다.

따라서, 정리해 보면 column을 추가하여 새로운 비즈니스 로직이 생기게 되는 경우에는 proxy model을 사용하지 않지만, 원본 모델과 같은 모델을 사용하는데 여기에 새로운 python 기능을 추가하고 싶다면 proxy model을 사용하면 된다는 것이다.



위에서 언급된 개념들

Multi-table inheritance

아래와 같은 두 가지 객체가 정의되어 있다고 하자. 이 때, RestaurantPlace를 상속받은 객체이다. 그러나 Restaurant는 Place의 데이터베이스에 속해 있는 것이 아니며 Place와는 별도로 생성되며 쿼리하게 된다.

이 때, Place의 모든 필드는 Restaurant에서 사용할 수 있는데, 그럼에도 역시 Place와 Restaurant는 별개로 존재한다.

from django.db import models

class Place(models.Model):
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=80)

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    serves_pizza = models.BooleanField(default=False)

Meta

메타 데이터

메타 데이터는 데이터에 대한 데이터로, ‘어떤 목적을 갖고 만들어진 데이터’이며 다른 데이터를 설명해 주는 데이터이다.

즉, 메타 데이터는 대량의 정보 가운데 찾고 있는 정보를 효율적으로 이용하기 위한 데이터로, 구조화된 정보를 분석 & 분류하고 부가적인 정보를 추가하기 위해 그 뒤에 함께 따라가는 정보를 말한다.

또한, 정보를 효율적으로 찾기 위해 일정한 규칙에 따라 콘텐츠에 부여되는 데이터라고도 할 수 있다.

예를 들면, 사진을 찍었을 때 카메라 정보, 촬영 시간, 노출, 플래시 사용 여부 등의 사진 정보를 저장하게 되는데 이 때 위치 정보를 메타 데이터로 이용하여 사진이 어디에서 촬영되었는 지를 파악하고 해당 지역에서 찍은 다른 사진을 검색할 때 사용할 수 있다.


Meta options

장고에서의 class Meta는 “필드가 아닌 다른 어떤 것”을 의미한다. 가령, ordering 혹은 db_table(테이블명), 사람이 읽기 편하도록 만든 verbose_name 등이 들어갈 수 있다.

Meta class를 사용하는 것은 선택적이며 필수가 아니다!


<abstract 속성>

장고의 Meta option들 중 ‘abstract’가 있다. 이 속성을 사용하면 여러 공통 정보들을 다른 여러 모델들에 넣을 수 있다. 그러면 이 때, Meta 속성에 abstract=True로 입력된 모델에 대한 데이터베이스 테이블은 생성되지 않는다. 그 대신, 해당 모델이 다른 모델들의 base class(부모 클래스)로 사용될 때, 자식 클래스에서 해당 base class에서 정의된 필드들을 가진 테이블이 만들어진다.

아래의 예시에서는 CommonInfo에 대한 테이블은 만들어지지 않는다. 그러나, Student 모델에서 CommonInfo를 상속 받았기 때문에 Student 모델에서 CommonInfo에 정의한 필드들이 생성되는 것이다.

from django.db import models

class CommonInfo(models.Model):
    name = models.CharField(max_length=100)
    age = models.PositiveIntegerField()

    class Meta:
        abstract = True

class Student(CommonInfo):
    home_group = models.CharField(max_length=5)


참고

1) 장고 공식문서

https://docs.djangoproject.com/en/3.2/topics/db/models/#proxy-models

https://docs.djangoproject.com/en/3.2/topics/db/models/#abstract-base-classes

2) 블로그

https://velog.io/@namukeu/Django-Proxy-Model-사용하기

https://wa-yeong.tistory.com/14

profile
쿄쿄
post-custom-banner

0개의 댓글