반응형

Django의 Proxy 모델은 하나의 데이터 모델을 가지고, 다른 인터페이스를 제공하는 클래스라고 생각하면 됩니다.

모델 상속의 경우, 각 subclass 에 대해서 새로운 데이터 테이블이 생성되지만, proxy 모델은 별도로 데이터 테이블을 생성하지 않고, 기존 테이블을 참조해서 사용하게 됩니다. 

 

Proxy 모델의 정의

Proxy 모델은 원본 모델 클래스를 상속받아, Meta 클래스에 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 MyPerson(Person):
    class Meta:
        proxy = True

 

 

Proxy 모델 활용 - method 재정의

아래 예시에서는 원본 데이터 클래스인 Person 에서는, 인스턴스 출력시, DB에 저장되어 있는 이름을 그대로 출력되고, Proxy 클래스인 MyPerson 에서는, 인스턴스 출력시, 이름이 대문자로 변경되어서 출력됩니다. 같은 데이터를 참조하면서, method 를 다르게 정의해서 사용할 수 있습니다. 

 

from django.db import models

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

    def __str__(self):
        return f"{self.firat_name} {self.last_name}"

class MyPerson(Person):
    class Meta:
        proxy = True
 
    def __str__(self):
       return super().__str__().upper()

 

Proxy 모델 활용 - manager: get_queryset

이번에는 proxy 모델과 manager를 이용해서, 원본 데이터를 필터링해서 관련 데이터만 사용하는 예시입니다.

먼저 SomeClass 라고 하는 데이터 모델을 정의하고, 세 개의 필드 status, title, content 를 정의합니다. 이어서 정의할 manager 클래스에서는 SomeClass의 status 값에 따라 원본 데이터를 필터해서 돌려 줄 수 있게 처리합니다. 그리고 마지막으로 proxy 모델들은 원본 데이터 클래스 (SomeClass) 를 상속하고, objects 에 해당 manager 클래스의 인스턴스를 지정해 줍니다. 

 

from django.db import models

STATUS_TYPES = (
    ('n', 'New'),
    ('i', 'In Process'),
    ('c', 'Completed'),
)

# 원본 데이터 클래스
class SomeClass(models.Model):
    status = models.CharField(max_length=1, choices=STATUS_TYPES)
    title = models.CharField(max_length=100)
    content = models.TextField(blank=True, null=True)

# 매니저 클래스
class NewStatusManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='n')

# 원본 데이터 테이블에서 status 가 'n' 인 데이터만 가지고 오는 proxy 클래스 
class NewStatusSomeClass(SomeClass):
    objects = NewStatusManager()
    class Meta:
    	proxy = True

# 매니저 클래스
class InProcessStatusManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='i')

# 원본 데이터 테이블에서 status 가 'i' 인 데이터만 가지고 오는 proxy 클래스
class InProcessStatusSomeClass(SomeClass):
    objects = InProcessStatusManager()
    class Meta:
    	proxy = True

# 매니저 클래스
class CompletedStatusManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='c')

# 원본 데이터 테이블에서 status 가 'c' 인 데이터만 가지고 오는 proxy 클래스
class CompletedStatusSomeClass(SomeClass):
    objects = CompletedStatusManager()
    class Meta:
    	proxy = True

 

 

 

 

Proxy 모델 활용 - manager: create

이번에는 proxy 클래스로 신규 레코드를 생성하는 케이스에 대해서 정의해 보겠습니다.

Proxy 모델에 연결된 manager 클래스에 create method 를 재정의해서, Proxy 형태를 구분하는 컬럼의 값을 지정해 줄 수 있습니다.

 

class SampleManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(type='sample')
        
    def create(self, **kwargs):
        kwargs.update({'type': 'sample'})
        return super().create(**kwargs)
        
...

params = {}
SampleManager.objects.create(**params)

 

 

반응형

+ Recent posts