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

0%

Multi-table inheritance 2편


Inheritance and reverse relations


multi-table 상속은 암시적으로, OneToOneField 를 사용하여 자식 클래스와 부모 클래스를 연결해 주기 때문에, 부모 클래스에서 자식 클래스로 이동이 가능해 집니다.


하지만, 이는 ForeignKey 와 ManyToManyField 관계들을 위한 기본 related_name 값을 사용합니다.


만일 우리가, ForeignKey 나 ManyToManyField 관게들을 부모의 서브클래스에 넣어준다면, 각 필드에 related_name 속성들을 지정해 주어야 합니다.


각 필드에 이 relate_name 속성을 지정해 주지 않는다면, Django는 유효성 에러를 발생 시킬겁니다.



더 읽어보기 »

Model 상속 (Multi-table inheritance )


Django 모델을 상속 받는데에 있어서 3가지 스타일이 존재합니다.


  1. Abstract base classes
  2. Multi-table inheritance
  3. Proxy Models

Multi-table inheritance


Django 모델에서 지원하는 두번째 모델 상속 방식은, Multi-table inheritance 입니다.


각 모델이 계층구조에서, 자체적으로 모델일 경우 입니다.

각 모델은 각자의 데이터베이스 테이블에 해당 되고, 각각 쿼리문을 보내거나 생성될수 있습니다.


상속 관계는, 자식 모델과 부모 모델의 연결고리를 만들어 놓습니다.


예를들면,

더 읽어보기 »


만약 우리가 ForeginKey 나 ManyToManyField 에 related_name 혹은 related_query_name 을 사용하고 있다면, 우리는 언제나 고유한 reverse name 과 query name 들을 해당 필드에 지정해 주어야 합니다.


이 related_name 과 related_query_name 부분에 대해서, 아주 심도있게 clarification 한 곳이 없으므로.


예시만 보고 지나갑니다.

더 읽어보기 »

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






Model Inheritance (Abstract Base Classes)


Abstract Base classes


Abstract base 클래스들은, 여러분들이 어떠한 공통된 정보들을, 다른 모델들에 넣고 싶을때에 유용하게 쓸수 있습니다.


Base 클래스를 작성한다음, Meta class 에다가, abstract=True 로 설정합니다.


그러면, 해당 모델은, 데이터베이스를 생성하는데에 사용되지 않습니다.


다른 모델들의 Base 클래스로 사용될때에는,

Base 클래스의 필드들이 자식 클래스들에 추가 됩니다.


예시를 들자면,


더 읽어보기 »

Model Inheritance (모델 상속)


Django 에서 모델 상속은, 파이썬에서 일반적인 클래스 상속을 하는것과 거의 비슷하게 작동합니다.


다만, django 의 기본에는 충실해야 합니다. 이것이 의미하는것은, Django 모델 클래스들은 django.db.models.Model 의 서브 클래스가 되어야 한다는 이야기 입니다.


여러분들이 결정해야 할 사항은 아래와 같습니다.


  1. 부모 모델이 자신의 모델이 될지
  2. 부모 모델은 단지 공통된 정보를 가지고, 자식 모델들을 통해서만 정보가 보이게 하게 할지

이 개념을 쉽게 이해하기 위해서는, 파이썬에서 클래스의 상속 개념을 잘 알고 있어야 합니다.



Django 에서는 상속에 대한 3가지 스타일들이 존재 합니다.


  1. 보통은, 자식 모델들의 필드에 대해서 타이핑 하기 싫을때, 부모 클래스가 정보만 가지게끔 사용할수 있습니다. 이 클래스는 절대로 분리되서 사용될수 없습니다. 따라서, Abstract base classes 들이 당신이 원하는것이 될겁니다.
  2. 이미 존재하는 모델 (다른 어플리케이션에 있는 모델)을 상속을 받고 있고, 각 모델이 각자의 데이터베이스 테이블을 가지고 있다면, Multi-table inheritance 를 사용할수 있습니다.
  3. 모델 필드의 수정 없이, 모델의 파이썬 레벨 동작을 고치고 싶다면, proxy models 를 사용하면 됩니다.

더 읽어보기 »

Overriding predefined model methods


여러분들이 커스터마이즈 하고 싶은 데이터베이스의 동작을 캡슐화 해주는 모델 메서드들도 존재 합니다.


특히 우리는 종종 save()delete() 의 동작 방식을 바꾸고 싶어 집니다.


save() 나 delete() 같은 메서드들을 override 해서 동작 방식을 바꾸는것도 가능하고,

다른 어떤 모델 메서드들을 override 해서 사용하는것도 가능합니다.


내장된 메서드, save() 같은 메서드를 override 하여 사용하는 고전적인 예시는,


하나의 객체를 저장할때마다 다른 무언가를 발생시키고 싶을 때입니다.


더 읽어보기 »

Model Methods


모델 클래스에는, 사용자 정의 메서드를 추가할수 있습니다. (row-level, 즉, 줄 단위)


Manager 메서드 (objects) 는, table 전체에 적용되고. 모델 메서드들은, 특정한 모델 인스턴스에 적용됩니다.


해당 모델의 인스턴스에 대해서, 특별한 비지니스 로직을 동작하고 싶을때에, 이런 모델 메서드를 사용해서. 하나의 모델에 모아놓고 사용할수 있습니다.


아래 예시에는, 몇가지 사용자 정의 메서드가 정의되어 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from django.db import models 


class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()

def baby_boomer_status(self):
# "Returns the person's baby-boomer status. "
# 해당 사람이, baby_boomer 세대인지 아닌지 판단합니다.
import datetime
if self.birth_date < datetime.datetime(1945, 8, 1):
return "Pre-boomer"
elif self.birth_date < datetime.datetime(1965, 1, 1):
return "Baby boomer"
else:
return "Post-boomer"

@property
def full_name(self):
# "Returns the person's full name"
# 해당 사람의 이름을 리턴합니다
return '%s %s' % (self.first_name, self.last_name)


더 읽어보기 »

Model Attributes


모델의 가장 중요한 속성은 Manager 입니다.


Manager 는

Django 데이터베이스 쿼리 운영을 제공 하는 인터페이스로,

데이터베이스에서 인스턴스들을 검색할때 사용 됩니다.

만약, 사용자 정의 Manager 가 정의되어 있지 않다면, 기본값으로, Manager 의 이름은 objects 입니다.


Manager 는 모델 클래스들을 통해서만 접근 가능합니다. 모델 인스턴스로는 접근이 가능하지 않습니다.


더 읽어보기 »

Models - Meta Options


Metadata

데이터의 집합체로 다른 데이터에 대한 설명과 정보를 제공합니다


모델에 metadata 를 부여할수 있습니다. 클래스 안에 Meta 클래스를 사용해서 부여할수 있습니다.


아래 예시와 같이 모델 클래스 안에 부가적으로, Meta 클래스를 넣어서 metadata 를 넣을수 있습니다.


1
2
3
4
5
6
7
8
9
from django.db import models 

class Ox(models.Model):
horn_length = models.IntegerField()

# 아래와 같이 Ox 모델 클래스 안쪽에 Meta 클래스를 넣어서 metadata 를 부여 할수 있습니다
class Meta:
ordering = ["horn_length"]
verbose_name_plural = "oxen"

필드가 아닌 무엇이든, 모델의 메타데이터가 될수 있습니다.


필드는, 메타 데이터가 될수 없습니.


더 읽어보기 »