본문 바로가기

Study/BackEnd

[Django] Django Model 상속 알아보기

회사에서 django를 다루면서, ORM을 공부할 일이 정말 많다.
그 중에서도 특히 model 상속과 관련된 부분을 따로 정리해보려고 한다.

1. 추상 기본 클래스 (Abstract Base Class)

추상 기본 클래스는 여러 다른 모델이 공통된 필드를 가지고 있어서,
해당 필드들을 여러번 반복해서 작성하는 비효율이 발생할 때 유용하다.

예를 들어서,
어느 대학교에 다니는 대학생들은 이름, 학번 등의 공통된 필드를 가지고 있고
과별로 졸업을 위해서 필요한 요건이 다르다.

이런 경우에 모델을 각각 생성해주려면 아래와 같은 형태가 될 것이다.

from django.db import models

class EducationStudent(models.Model):
  name = models.CharField(verbose_name = "student name", max_length = 20)
  student_id = models.intField(verbose_name = "student id", max_length = 8)
  teaching_practice = models.BooleanField(verbose_name = "교직 이수 여부")
 
class ComputerScienceStudent(models.Model):
  name = models.CharField(verbose_name = "student name", max_length = 20)
  student_id = models.intField(verbose_name = "student id", max_length = 8)
  engineer_information_processing = models.BooleanField(verbose_name = "정보처리기사 취득 여부")


위와 같은 경우에는 세개 중 두개가 공통 필드임에도 불구하고 중복해서 생성해주어야 하는 것을 볼 수 있다.
과가 50개가 넘어간다면? 이런 수고를 매우 많이 반복해주어야 한다.

이럴 때, 추상 기본 클래스를 사용하면 번거로움을 줄이고 더 직관적인 코드를 작성할 수 있다.

from django.db import models

# 공통된 정보인 name, student_id를 추상 기본 클래스 내 필드로 생성
class Student(models.Model):
  name = models.CharField(verbose_name = "student name", max_length = 20)
  student_id = models.IntField(verbose_name = "student_id", max_length = 8)

  class Meta:
    abstract = True

# 추상 기본 클래스를 상속받아서 각 과에 맞게 자식 클래스 생성
class EducationStudent(Student):
  teaching_practice = models.BooleanField(verbose_name = "교직 이수 여부")

class ComputerScienceStudent(Student):
  engineer_information_processing = models.BooleanField(verbose_name = "정보처리기사 취득 여부")


추상 기본 클래스를 사용하기 위해서는 부모 클래스의 Meta 클래스에서 abstract = True로 설정해주어야 한다.

또한, 자식 클래스가 자신만의 Meta 클래스를 선언하지 않으면 부모 클래스의 Meta 클래스를 상속받는다.

이 때, 부모 클래스는
1. Manager를 갖지 않고
2. 일반 django model로 사용이 불가능하며
3. 인스턴스화나 저장이 불가능하다.

즉, 부모 클래스는 테이블이 생성되지 않으며 실제적인 의미의 상속은 일어나지 않는다.

2. 다중 테이블 상속 (multi table inheritance)

추상 기본 클래스와 달리, 다중 테이블 상속에서는 각 모델이 자체적으로 모델이다.
즉, 각 모델이 자체적으로 데이터베이스 테이블에 해당하며 개별적으로 생성과 쿼리가 가능하다는 뜻이다.

또한, 자식 클래스가 하나의 부모 클래스만을 상속받는 것이 아닌 여러개의 부모 클래스를 상속받을 수 있다.

from django.db import models

class Student(models.Model):
  name = models.CharField(verbose_name = "student name", max_length = 20)
  student_id = models.IntField(verbose_name = "student id", max_length = 8)

class EducationStudent(Student):
  teaching_practice = models.BooleanField(verbose_name = "교직이수 여부")

class ComputerScienceStudent(Student):
  engineer_information_processing = models.BooleanField(verbose_name = "정보처리기사 취득 여부")


다중 테이블 상속은 각각의 자식 클래스들에게 공통 필드도 상속해주면서 해당 자식 클래스의 테이블들을 하나의 부모 테이블에서 모아서 관리할 필요가 있을 때 유용하다.

또한 이런 경우에 django-model-utils의 InheritanceManager를 이용하면 자식 클래스의 복잡한 상속 내용들을 일일히 다 알지 못하더라도 부모 모델만을 이용해서 자식 모델들을 쉽게 다룰 수 있다.

이 InheritanceManager에 대해서는 다음 포스팅에서 상세하게 다룰 예정이다!!

 

다루는 코드가 복잡해지면서 공부할 내용이 점점 느는 것 같다.
그럼 다음 포스팅에서 만나용!!