Django의 모델 상속
문제
나는 현재 의료기기를 판매하는 회사에서 일하고 있다.몇 달 전, 나의 임무는 Django를 사용하여 시스템을 구축하는 것이다. 이 시스템은 우리의 판매 대표가 우리의 제품을 쉽게 검색하고 견적을 만들어 고객에게 보낼 수 있도록 한다.이 시스템의 요구 사항은 다음과 같습니다.
Product
클래스를 가지고 있다. 이 클래스는 모든 유형의 통용되는 속성을 가지고 있으며 각 제품 유형은 하나의 하위 클래스로 그 자체의 유일한 속성을 추가할 수 있다.Product
에 속하는 모든 제품을 검색하는 것처럼 간단하다Product
개체의 목록을 저장할 수 있으며 제품 유형을 알 수 없습니다Product
의 각 하위 클래스를 각각 Django의 관리 사이트에 등록할 수 있다다중 테이블 상속
다중 테이블 계승은 초클래스와 모든 하위 클래스가 자신의 데이터베이스 테이블에 비치는 곳이다.공유 필드는 클래스 테이블에 저장되고, 유형별 필드는 각자의 테이블에 저장됩니다.그리고 모든 하위 클래스 테이블에는 부모 클래스 테이블에 해당하는 줄의 id를 포함하는 추가 열이 있습니다.Django에서는 모델 클래스가 이렇게 보일 수 있습니다.
from django.db import models
class Product(models.Model):
part_number = models.CharField(max_length=25)
price = models.CharField(max_length=25)
class Label(Product):
dimensions = models.CharField(max_length=25)
class FaceMask(Product):
COLOR_CHOICES = [
('Blue', 'Blue'),
('White', 'White')
]
color = models.CharField(max_length=25, choices=COLOR_CHOICES)
책상이 이렇게 보여요.너무 좋아요.이제 우리는 각 제품 유형을 관리자에게 추가할 수 있으며, 그곳에서 그것들을 단독으로 편집할 수 있다.이렇게 범용 제품을 추가할 수도 있습니다
Quote
.class Quote(models.Model):
name = models.CharField(max_length=25)
products = models.ManyToManyField(Product)
단일 계승
말 그대로 단표 계승은 하나의 표만 사용하여 초클래스와 모든 하위 클래스의 속성을 저장한다.
type
열을 사용하여 표구별 분자류 유형이 아니라 특정 줄에 대응하는 대상 유형을 이해합니다.Django에서는 다음과 같이 보입니다.class Product(models.Model):
# Type field
TYPE_CHOICES = [
('Label', 'Label'),
('Face Mask', 'Face Mask')
]
product_type = models.CharField(max_length=25, choices=TYPE_CHOICES)
# Common Fields
part_number = models.CharField(max_length=25)
price = models.CharField(max_length=25)
# Label fields
label_dimensions = models.CharField(max_length=25)
# Face Mask fields
COLOR_CHOICES = [
('Blue', 'Blue'),
('White', 'White')
]
face_mask_color = models.CharField(max_length=25, choices=COLOR_CHOICES)
책상이 이렇게 보여요.처음에 나는 이런 상속 방식에 만족하지 않았다. 왜냐하면 나는 어떻게 관리에서 모든 유형을 단독으로 표시해야 하는지 잘 모르기 때문이다.Django의 에이전트 모델과
Manager
클래스를 만날 때까지.프록시 모델을 사용하면 우리는 여러 테이블과 같은 효과를 계승할 수 있을 뿐만 아니라 모든 내용을 한 테이블에 저장할 수 있다.class LabelManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(product_type='Label')
class Label(Product):
objects = LabelManager()
class Meta:
proxy = True
class FaceMaskManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(product_type='Face Mask')
class FaceMask(Product):
objects = FaceMaskManager()
class Meta:
proxy = True
Django의 클래스 Manager
에서는 객체를 질의할 때 기본 필터를 적용할 수 있습니다.예를 들어 상기 코드를 사용하면 우리는 Label.objects.all()
모든 Label
대상을 얻을 수 있다.proxy = True
메타 옵션은 Django가 Label
또는 FaceMask
객체에 대해 별도의 테이블을 만들지 말라고 알려줍니다.우리는 관리자에게 에이전트 모델을 등록할 수 있다. 우리는 관리자에게 관련 필드만 표시하라고 알려줄 수 있을 뿐이다.@admin.register(Label)
class LabelAdmin(admin.ModelAdmin):
fields = ('part_number', 'price', 'dimensions')
@admin.register(FaceMask)
class FaceMaskAdmin(admin.ModelAdmin):
fields = ('part_number', 'price', 'color')
우리의 선택
단일 테이블 계승의 가장 큰 장점은 한 테이블에서 조회를 실행하기만 하면 필요한 정보를 얻을 수 있다는 것이다.다중 테이블 계승은 초클래스와 하위 클래스를 연결해야 한다.우리는 우리가 대량의 제품 조회를 진행할 것을 알고 있으며, 모든
JOIN
조작이 우리의 응용 프로그램을 늦추지 않을까 걱정한다.그 밖에 우리는 처음에 두 가지 제품 유형만 저장할 계획이었기 때문에 제품표가 매우 커질 것이라고 생각하지 못했다.이러한 이유로 우리는 단표 계승을 선택하여 제품 데이터를 모델링한다.그러나 나는 다중 계승이 더 좋은 선택이 될 수 있다고 생각하기 시작했다.응용 프로그램의 수요에 따라 우리는 더 많은 제품 유형을 저장해야 한다.우리의 제품 유형 사이에 공통된 속성이 많지 않기 때문에 제품 표에 대량의 공백 항목이 나타났다.이것은 제품표를 혼란스럽고 관리하기 어렵게 할 수 있으니, 나는 비교적 느린 조회를 따져볼 만하다고 생각한다.고맙게도 단표 계승 작업은 매우 잘 되었다. 내가 말한 바와 같이 우리는 확실히 그 중에서 성능 우위를 얻었다.
결론
내가 여기서 배운 경험은 만약 하위 클래스에 많은 공통된 필드가 없다면 많은 표 계승이 하나의 방법이라고 생각한다.그것은 메모리에 있어서 효율이 더욱 높다. 왜냐하면 대량의 공백 항목으로 데이터베이스를 팽창시킬 위험을 무릅쓸 필요가 없기 때문이다.그러나 단일 계승은
JOIN
조작이 필요하지 않기 때문에 항상 더욱 효율적인 조회 방식이다.대부분의 일과 마찬가지로, 올바른 선택은 당신의 용례에 달려 있습니다.
Reference
이 문제에 관하여(Django의 모델 상속), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/zachtylr21/model-inheritance-in-django-m0j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)