[Django 공식문서 번역] Models - 4. Inheritance

이 글은 본인이 공부를 목적으로 공식문서를 읽으며 정리/번역한 글로서 오역이 있을 수 있을 수 있습니다. 또한 본인이 이미 알고 있거나 불필요하다 느끼는 내용들은 누락될 수 있습니다.

Model Inheritance

장고에는 3가지 종류의 상속이 있다.

1. 대부분의 경우, parent class가 child model에서 중복되게 선언해줘야되는 필드를 대신가지기 위해 사용되는 경우가 있다. 이 경우, parent class는 홀로 사용되지는 않는다. 이 경우에는 Abstract base class를 사용하면 된다.

2. 만약 이미 존재하는 model을 그대로 가져오면서 각각의 model이 각자 자신만의 database table을 가지길 바란다면 Multi-table inheritance를 사용하면 된다.

3. 마지막으로, 만약 model의 필드를 일체 건드리지 않으면서 Python-level의 동작을 변경하고 싶다면 Proxy model을 사용하면 된다.


Abstract base classes

Abstract base class는 공통된 정보를 여러개의 model에 넣고 싶을때 유용하다. base class를 작성한다음 Meta class에 abstract = True를 작성하면 된다. 이 model은 database의 model로 생성되지 않고 다른 model의 base class로서만 사용된다.
(base class에 선언된 Meta Class또한 상속된다)

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)

Multi-table inhertance

각각의 model들은 자신만의 database table을 가지며 따로 쿼리되고 생성될 수 있다. 이 방식으로 상속하면 child와 parent간에 링크를 생성한다(장고가 자동으로 OneToOneField를 생성한다)

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)
이렇게 선언되었다면:
>>> Place.objects.filter(name="Bob's Cafe")
>>> Restaurant.objects.filter(name="Bob's Cafe")
이렇게 Place의 모든 field는 Restaurant안에 존재한다.(단, 각기 다른 테이블에 들어있음)


그리고 만약 Restaurant인 Place라면:
>>> p = Place.objects.get(id=12)
# If p is a Restaurant object, this will give the child class:
>>> p.restaurant
<Restaurant: ...>
이렇게 One-to-one relationship을 통해 접근할 수 있다.

[추측하건데, 위의 예시에서 원본 Place의 테이블이 존재하고, Restaurant가 Place를 상속받아 새로 table이 생성될때 Restaurant용 Place 테이블이 새로 생성되는 것 같다.]

Proxy models

multi-table inheritance를 사용한다면 각각의 subclass model을 위해 새로운 database table이 생성된다. 하지만 가끔 model의 Python 작업만 수정하고 싶을 때가 있다 - default manager를 수정한다거나 새로운 method를 추가한다거나 하는 경우 말이다.

Proxy model에서 데이터를 수정/삭제/추가할 경우 실제 table에 영향을 미친다.

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

    def do_something(self):
        # ...
        pass




















댓글

이 블로그의 인기 게시물

[Django REST Framework] create() vs perform_create()

[웹 보안] CORS란?

3. GRAPHQL FRAGMENTS