장고의 ORM(객체 관계형 매핑) 프레임워크에서 모델 상속을 활용하면 데이터베이스 모델 간에 계층적 연결을 생성하여 객체 지향 프로그래밍의 이상을 촉진하고 코드 재사용성, 확장성 및 깔끔함을 향상시킬 수 있습니다.

포괄적인 웹 애플리케이션 개발 또는 보다 제한된 작업에서 모델 상속을 통합하면 중복된 노력을 최소화하고 동작의 통일성을 촉진하는 등 여러 가지 이점을 얻을 수 있습니다.

장고의 모델 상속 유형

장고 프레임워크는 다음과 같은 세 가지 모델 상속 모드를 위한 메커니즘을 제공합니다.

추상 베이스 클래스는 다른 클래스를 만들기 위한 청사진 또는 템플릿으로, 파생 클래스에서 상속할 수 있는 공통 메서드 및 속성 집합을 제공합니다.

다중 테이블 상속은 단일 클래스가 여러 테이블에서 파생되어 단일 개체 내에서 서로 다른 소스의 데이터를 결합할 수 있는 시나리오를 말합니다. 이 기술은 다양한 소스의 정보를 통합해야 하는 복잡한 데이터 구조를 다룰 때 유용할 수 있습니다.

프록시 모델은 복잡한 시스템과 환경 사이의 중개자 역할을 하는 일종의 수학적 표현으로, 전자를 단순화하고 쉽게 분석하는 동시에 어느 정도의 정확성을 유지하면서 표현할 수 있도록 해줍니다. 이러한 모델은 시스템의 동작을 이해하고 다양한 조건에서 시스템이 어떻게 반응할지 예측하는 데 사용할 수 있습니다.

각 유형의 모델 상속을 활용하는 것은 고유한 방식으로 유용하며 특정 애플리케이션에 가장 적합합니다.

추상 베이스 클래스

추상 베이스 클래스를 활용하면 여러 모델 간에 공유 특성을 설정할 수 있습니다. 겹치는 속성을 가진 두 모델이 있는 경우 추상 베이스 클래스를 사용하여 이러한 공통점을 나타낼 수 있습니다. 다음 그림을 참조하세요:

 class Customer(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()
    customer_id = models.IntegerField()

class Seller(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()
    seller_id = models.IntegerField()

앞서 언급한 코드는 이름과 이메일이라는 두 가지 공유 속성을 가진 두 개의 별개의 Django 모델, 즉 Customer와 Seller를 설정합니다. 이러한 중복을 피하기 위해 Customer와 Seller 모델의 공통 기능을 모두 포함하는 별도의 모델을 만들어 추상 엔티티로 렌더링할 수 있습니다.

 class UserInfo(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    class Meta:
        abstract = True

앞서 언급한 코드 세그먼트는 새로운 모델을 설정하고 해당 추상 속성에 ‘True’라는 값을 할당합니다. 결과적으로 모델은 추상적인 것으로 간주되어 장고에서 데이터베이스 내에 해당 테이블을 생성하지 못하게 됩니다.

이 글도 확인해 보세요:  Vite로 React 앱을 설정하는 방법

고객과 셀러의 두 모델은 다음과 같은 방식으로 수정할 수 있습니다:

 class Customer(UserInfo):
    customer_id = models.IntegerField()

class Seller(UserInfo):
    seller_id = models.IntegerField()

앞서 언급한 코드 스니펫은 고객 및 판매자 모델이 기본 클래스 Model이 아닌 UserInfo 모델에서 파생되는 인스턴스를 보여줍니다.

`admin.py` 파일에 필요한 구성을 통합하면 관리 패널에서 등록된 모델을 관찰할 수 있는 기능을 사용할 수 있습니다.

 from .models import Customer, Seller

admin.site.register(Customer)
admin.site.register(Seller)

 python manage.py makemigrations \
    && python manage.py migrate \
    && python manage.py runserver

관리 웹사이트로 이동하여 수퍼유저 자격 증명을 사용하여 액세스 권한을 얻으십시오. 로그인하면 각 모델에 대해 세 가지 입력 필드를 사용할 수 있음을 알 수 있습니다.

이 인스턴스는 Django가 고객 및 판매자 모델에 대한 테이블을 생성한 방법을 보여줍니다. UserInfo 모델은 추상적인 것으로 표시되어 있으므로 해당 테이블이 없음을 나타냅니다.

다중 테이블 상속

상속을 위해 다중 테이블을 사용하는 경우 상위 모델이 하위 모델과 함께 데이터베이스의 자체 테이블 내에 존재해야 할 수 있습니다.

부모 모델이 데이터베이스의 테이블로 표시되지 않는 추상 기본 클래스 상속과 달리 다중 상속을 사용하면 부모 모델에 대한 테이블이 생성됩니다.

다중 테이블 상속은 자식 모델이 부모 모델의 모든 속성과 메서드를 획득하는 동시에 고유한 속성을 보유하는 것을 포함합니다. 외래 키의 활용은 부모 모델과 자식 모델 간의 연관성을 나타내는 역할을 합니다.

다중 테이블 상속의 개념은 데이터베이스에서 여러 테이블을 사용하여 각 테이블에 고유한 속성 및 동작 집합을 갖는 여러 클래스를 나타내는 것입니다. 이를 통해 기존의 단일 테이블 상속 접근 방식보다 실제 객체와 관계를 더 유연하게 모델링할 수 있습니다.

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

    def get_name(self):
        return f"{self.first_name} {self.last_name}"

    class Meta:
        abstract = True

class Employee(Person):
    employee_id = models.CharField(max_length=20)
    department = models.CharField(max_length=100)
    salary = models.FloatField()
    dob = models.DateField()

class Manager(Employee):
    title = models.CharField(max_length=100)

본 명세서에서는 세 가지 모델을 생성하는 방법을 설명하며, 첫 번째 모델은 “사람”으로 명명됩니다. 이 모델은 개인의 이름과 성만 구현하며, 두 가지 모두 추상적인 방식으로 표현됩니다.

이 글도 확인해 보세요:  내부에서 REST API 호출을 수행하는 방법 VS 코드

직원 모델은 개인 모델의 하위 유형으로, 두 모델이 공유하는 공통 특성을 유지하면서 고유한 고유 속성을 가지고 있습니다. 추상적인 엔티티인 개인 모델과 달리 직원 모델은 데이터베이스 테이블 형태의 물리적 표현을 가지고 있습니다.

‘관리자’라는 이름의 최종 모델은 ‘직원’ 모델의 모든 속성을 통합하고 ‘직위’라는 속성을 추가로 포함합니다.

앞서 언급한 Employee 모델과 Manager 모델 간의 연결은 다중 테이블 상속으로 분류할 수 있습니다. 이러한 모델을 구체화하려면 admin.py를 통해 마이그레이션하고 서버를 시작한 다음 관리자 패널에 액세스합니다. 이 시점에서 Django에 의해 두 개의 테이블이 생성되는 것을 관찰해야 합니다.

새 관리자를 추가하는 프로세스에는 Employee 모델의 기존 필드를 활용하면서 동시에 Manager 모델에 고유한 속성을 통합하는 작업이 포함됩니다.

프록시 모델

프록시 모델을 활용하면 새로운 데이터베이스 테이블을 설정할 필요 없이 기존 모델에서 파생된 새로운 모델을 개발할 수 있습니다. 이러한 시나리오에서는 프록시 모델과 원본 모델이 동일한 테이블을 공유합니다. 프록시 모델을 구현하면 사용자 지정 모델을 생성하고 기본 관리자를 수정할 수 있습니다.

주어진 문장을 좀 더 설득력 있는 언어로 바꾸도록 도와드릴 수 있나요?

 class ProxyModel(BaseModel):

    class Meta:
        proxy = True

프록시 모델은 기존 기본 모델을 사용할 수 있고 추가 기능을 통합하는 사용자 지정 변형을 만들어야 할 때 언제든지 활용할 수 있습니다. 이에 대한 간단한 예시

 class Post(models.Model):
    title = models.CharField(max_length=30)
    author = models.CharField(max_length=30)

    def __str__(self):
        return self.title

class ProxyPost(Post):

    class Meta:
        proxy = True

본 코드에서는 “Post”와 “MyPost”라는 두 가지 모델을 생성하도록 지정합니다. 전자는 “title”과 “author”로 지정된 두 개의 어트리뷰트로 구성되며, 후자는 전자의 서브클래스인 “ProxyPost”로 알려져 있습니다.

이전에 정의된 모델을 이동하고 테이블에 포스트 모델에 해당하는 새 레코드를 생성하는 프로세스에는 기술적 전문 지식과 세심한 주의가 필요합니다. 여기에는 데이터베이스 스키마를 업데이트하고, 데이터가 올바르게 구조화되었는지 확인하고, 테이블 간의 모든 관계가 유지되는지 확인하는 작업이 포함됩니다. 마이그레이션 프로세스를 철저히 테스트하여 결과 데이터에 오류나 불일치가 없는지 확인하는 것이 중요합니다.

이 글도 확인해 보세요:  Rust의 제네릭 형식 알아보기

글을 제출할 때 프록시 글 표를 참조하세요. 게시글 표에 제출한 글은 그 안에서 찾을 수 있습니다.

프록시 글에 대한 업데이트는 기본 글에 상호 영향을 미치므로 데이터베이스 테이블에 대한 공유 특성을 증명합니다.

프록시 모델의 str() 메서드는 객체가 문자열로 변환될 때 객체의 값을 표시하기 위해 print() 함수를 사용하는 Python의 객체 문자열 표현 프로토콜을 활용하여 수정할 수 있습니다.

 class ProxyPost(Post):

    class Meta:
        proxy = True
        ordering = ["title"]

    def __str__(self):
        return self.author

이 조정은 제목이 아닌 작성자를 결정 요인으로 하여 ProxyPost의 문자열 표현 방식을 변경합니다.또한 프록시 모델의 배열은 이제 사용자 지정 ID 필드 대신 제목을 기반으로 합니다.

프록시 모델을 사용할 때는 프록시 모델 자체 내에 사용자 지정 속성을 포함할 수 없다는 점을 명심해야 합니다. 프록시 모델은 일반적으로 다양한 동작을 수용하기 위해 단일 모델을 조정해야 하는 상황에서 사용됩니다.

프록시 모델을 사용하면 필드 구성이나 기본 데이터베이스 테이블 구조를 변경하지 않고도 속성 및 데이터 소스를 조작하는 방식으로 기존 모델의 동작을 수정할 수 있습니다.

코드 재사용성 및 조직 구조를 위한 모델 상속 활용

다양한 모델 상속 전략의 구현을 통해 프로젝트에 활용할 수 있는 재활용 가능하고 체계적으로 정리된 코드를 생성할 수 있습니다.

모델 상속을 활용하면 중복 코드를 제거하고 코드베이스의 가독성과 유지보수성을 전반적으로 향상시키면서 확장성을 높일 수 있습니다. 또한 직관적인 탐색 메커니즘을 제공하여 개발 팀 내 원활한 협업을 지원합니다.

장고는 모델 상속 외에도 템플릿 상속을 제공하여 프로젝트 템플릿을 효율적으로 관리하고 구성할 수 있습니다.

By 최은지

윈도우(Windows)와 웹 서비스에 대한 전문 지식을 갖춘 노련한 UX 디자이너인 최은지님은 효율적이고 매력적인 디지털 경험을 개발하는 데 탁월한 능력을 발휘합니다. 사용자의 입장에서 생각하며 누구나 쉽게 접근하고 즐길 수 있는 콘텐츠를 개발하는 데 주력하고 있습니다. 사용자 경험을 향상시키기 위해 연구를 거듭하는 은지님은 All Things N 팀의 핵심 구성원으로 활약하고 있습니다.