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

0%

Django Models 17편 - Model 상속 (Abstract Base Class) 2

Meta Inheritance


abstract base class가 생성될때에, django 는 base class 안에 선언된 Meta 클래스를 속성으로 만들어 줍니다. 만약 하나의 자식 클래스안에, 해당 자식 클래스를 위한 Meta class 가 정의되어 있지 않다면, 부모의 Meta 를 상속 받을것 입니다.


만약 자식 클래스가, 부모의 Meta 클래스를 확장하고 싶다면,

자식 클래스는, 부모의 Meta 클래스를 자식 클래스 내에 있는 Meta 에서 상속 받으면 됩니다.


코드 예시를 들자면,


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

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

class Meta:
abstract = True
ordering = ['name']

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

class Meta(CommonInfo.Meta):
db_table = 'student_info'

Django 는 기본적으로, abstract base 클래스의 Meta class 에 대한 조정사항을 가집니다. Meta 속성을 설치하기 이전에, abstract=False 로 지정합니다.


이것이 의미하는바는,

abstract 클래스의 자녀들은 자동으로 그리고 스스로는 abstract 클래스가 되지 않는다는것을 의미합니다.


물론, 다른 abstract 클래스를 상속받는 Abstract 클래스를 만드는것도 가능합니다.

단지 만들때마다, 명시적으로, abstract=True 를 지정해주는것만이 필요할 뿐입니다.


어떠한 속성들은 Abstract base class 의 Meta 안에 포함되는것이 이상해 보일때가 있습니다.


예를들면, db_table 을 포함한다면, 모든 자식 클래스들이 같은 데이터베이스 테이블을 사용하게 된다는 의미가 됩니다. 이렇게 설정하면, 매우 일이 이상해 집니다.


마치며..


자식 클래스에 있는 Meta Class 도 부모 클래스에 있는 Meta 클래스를 상속 받을수 있습니다.


연습도 해볼겸, 인스턴스 생성후, 속성값들을 확인해 봅니다.


1
2
3
4
5
6
7
8
9
10
In [1]: colin = Student.objects.create(name="Colin Firth", age=60, home_group="king")                                                                                     

In [2]: colin.Meta
Out[2]: abstractbaseclasses.models.CommonInfo.Meta

In [4]: colin.name
Out[4]: 'Colin Firth'

In [5]: colin.age
Out[5]: 60

Student class 안에 Meta 클래스에 db_table 이 데이터베이스 테이블 명이 된것을 확인할수 있습니다.


CommonInfo 클래스 안에 존재하는 Meta 클래스에, 이 db_table 속성을 넣어두면,

CommonInfo 클래스를 상속하는 모든 자식 클래스들의 데이터베이스 테이블명이 모두 하나로 동일하게 될겁니다. 그렇게 되면, 조금 이상한 일이 될겁니다.