Django의 모델 상속

12906 단어 djangodesigndatabase

문제


나는 현재 의료기기를 판매하는 회사에서 일하고 있다.몇 달 전, 나의 임무는 Django를 사용하여 시스템을 구축하는 것이다. 이 시스템은 우리의 판매 대표가 우리의 제품을 쉽게 검색하고 견적을 만들어 고객에게 보낼 수 있도록 한다.이 시스템의 요구 사항은 다음과 같습니다.
  • 우리는 몇 가지 제품 유형이 있다.어떤 속성은 모든 유형에 대해 통용되고, 어떤 속성은 특정 유형에 대해 유일하다.
  • 모든 제품 유형을 동시에 검색할 수 있어야 합니다.
  • 한 대표는 여러 개의 견적을 낼 수 있으며, 각 견적에는 하나 이상의 제품이 있다.제품은 어떤 종류든지 사용할 수 있다.
  • 모든 제품 유형은 Django의 관리 사이트에 자신의 부분이 있어야 해당 제품 매니저가 데이터에 들어가고 관리할 수 있다.
  • 이 점에서 나는 계승이 우리의 데이터 모델에서 중요한 역할을 할 것이라는 것을 잘 알고 있다.계승은 모든 수요를 잘 해결했다.
  • 우리는 기본Product 클래스를 가지고 있다. 이 클래스는 모든 유형의 통용되는 속성을 가지고 있으며 각 제품 유형은 하나의 하위 클래스로 그 자체의 유일한 속성을 추가할 수 있다.
  • 모든 제품 유형에서 검색하는 것은 Product에 속하는 모든 제품을 검색하는 것처럼 간단하다
  • 견적은 Product 개체의 목록을 저장할 수 있으며 제품 유형을 알 수 없습니다
  • 우리는 Product의 각 하위 클래스를 각각 Django의 관리 사이트에 등록할 수 있다
  • 나는 여전히 계승이 어떻게 데이터베이스로 바뀌어야 하는지 잘 모르겠다.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 조작이 필요하지 않기 때문에 항상 더욱 효율적인 조회 방식이다.대부분의 일과 마찬가지로, 올바른 선택은 당신의 용례에 달려 있습니다.

    좋은 웹페이지 즐겨찾기