[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
댓글
댓글 쓰기