2017-02-02 12 views
2

상속을 사용하여 모델을 구현하고 싶습니다.이 패키지는 django-polymorphic입니다. 하지만 장고 모델에서 상속에 대해 읽고 있었고 거의 모든 페이지에서 부모 모델에 abstract = True을 사용하는 것이 좋습니다. 서브 클래스의 필드를 복제하여 쿼리를 더 빠르게 만듭니다.Django Polymoprhic

나는 몇 가지 테스트를 수행하고이 라이브러리는 추상적 인 가변적이고을 사용하여 사용하지 않는 것을 발견했습니다

class Parent(PolymorphicModel): 
    parent_field = models.TextField() 

class Child(Parent): 
    child_field = models.TextField() 

This results in: 

부모 테이블 :

| app_parent| CREATE TABLE `app_parent` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `parent_field` longtext NOT NULL, 
    `polymorphic_ctype_id` int(11), 
    PRIMARY KEY (`id`), 
    KEY `app_polymorphic_ctype_id_a7b8d4c7_fk_django_content_type_id` (`polymorphic_ctype_id`), 
    CONSTRAINT `app_polymorphic_ctype_id_a7b8d4c7_fk_django_content_type_id` FOREIGN KEY (`polymorphic_ctype_id`) REFERENCES `django_content_type` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 

Child table: 

| app_child | CREATE TABLE `app_child` (
    `parent_ptr_id` int(11) NOT NULL, 
    `child_field` varchar(20) NOT NULL, 
    PRIMARY KEY (`parent_ptr_id`), 
    CONSTRAINT `no_parent_ptr_id_079ccc0e_fk_app_parent_id` FOREIGN KEY (`parent_ptr_id`) REFERENCES `app_arent` (`id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 | 

내가 내 자신의 클래스를 사용해야 어떤 추상적 인 사용 필드 또는이 막대기해야합니까?

+0

왜 장고 - 다형성을 사용하고 싶습니까? 너의 이유는 무엇인가? 나는이 도서관을 좋아한다. 왜냐하면 그것은 나를 위해 뭔가를 풀어주기 때문이다. 그것은 당신을 위해 무엇을 해결해야합니까? – guettli

+0

나는 상속을 사용하고자하는 비슷한 테이블이 많이있다. 내 코드를 단순하게하고 싶습니다. 나는 똑같은 5 개의 테이블과 변경 필드를 통과하기를 원하지 않습니다. 그러나 나는 정말 느린 SQL 쿼리를 원하지 않지만,이 패키지가 추상적 인 필드를 사용하지 않는다는 것을 알면 내 성능에 어떤 영향을 미치는지 알 수 없다. –

답변

0

부모 테이블에 쿼리 할 수 ​​있어야합니까?

Parent.objects.all() 

예, 다음 대부분의 아마 당신이 abstract=False로 멀티 테이블 상속을 사용해야 할 경우

.

모델 상속을 abstract=False과 함께 사용하면 더 많은 데이터베이스 관계로 더 복잡한 데이터베이스 스키마를 얻을 수 있습니다. 자식 인스턴스를 생성하는 데 1 (부모 및 자식 테이블) 대신 2 개의 삽입이 필요합니다. 하위 데이터를 쿼리하려면 테이블 조인이 필요합니다. 그래서이 방법은 확실히 단점이 있습니다. 그러나 일반적인 열 데이터를 쿼리 할 때 장고에서 지원하는 것이 가장 좋습니다.

장고 다형성은 부모 개체 만 갖는 하위 클래스를 식별 할 수있는 추가 열 polymorphic_ctype을 추가하여 표준 장고 모델 상속을 기반으로합니다.

abstract=True을 사용하여 유사한 결과를 얻는 데 사용할 수있는 다양한 방법이 있습니다. 그러나 종종 더 복잡한 쿼리 코드가 생성됩니다.

abstract=True을 사용하는 경우 모든 하위의 공통 데이터를 쿼리하는 방법에 대한 2 가지 예가 있습니다.

  • 체인화 여러 쿼리

    수동으로 여러 테이블을 결합하는 데이터베이스보기를 만들 데이터베이스 뷰를 사용

    def query_all_childs(**kwargs): 
        return chain(
         Child1.objects.filter(**kwargs) 
         Child2.objects.filter(**kwargs) 
        ) 
    
  • (이는 post-migrate 신호에 SQL 코드를 부착하여 수행 할 수있다) :

    create database view myapp_commonchild 
    select 'child1' as type, a, b from child1 
    union all 
    select 'child2' as type, a, b from child2 
    

    콘크리트 - 상위 모델 만들기 managed=False. 이 플래그는 django가 데이터베이스 마이그레이션에서 테이블을 무시하도록 지시합니다 (우리는 수동으로 데이터베이스 뷰를 생성했기 때문에).

    class Parent(models.Model): 
        a = CharField() 
        b = CharField() 
    
    class CommonChild(Parent): 
        type = models.CharField() 
        class Meta: 
         managed = False 
    
    class Child1(Parent): 
        pass 
    
    class Child2(Parent): 
        pass 
    

    이제 CommonChild.objects.all()을 쿼리하고 하위 클래스의 일반 필드에 액세스 할 수 있습니다. 성능의 말하기

, 나는 당신의 테이블이 얼마나 큰 알 또는 얼마나 무거운 것은 읽기/쓰기가 있지만, 대부분의 아마 abstract=False을 사용하여 눈에 띄는 방식으로 성능에 영향을주지 않습니다하지 않습니다.