Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django Polymoprhic_Python_Django_Django Polymorphic - Fatal编程技术网

Python Django Polymoprhic

Python Django Polymoprhic,python,django,django-polymorphic,Python,Django,Django Polymorphic,我想使用继承实现模型,我发现这个包django-polymorphic。但我在阅读django模型中的继承,我发现他们几乎每页都建议在父模型中使用abstract=True。这将复制子类的字段,从而加快查询速度 我做了一些测试,发现这个库没有使用抽象变量: class Parent(PolymorphicModel): parent_field = models.TextField() class Child(Parent): child_field = models.Text

我想使用继承实现模型,我发现这个包
django-polymorphic
。但我在阅读django模型中的继承,我发现他们几乎每页都建议在父模型中使用
abstract=True
。这将复制子类的字段,从而加快查询速度

我做了一些测试,发现这个库没有使用抽象变量:

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 |

我应该使用我自己的类来使用抽象字段,还是应该坚持这样做?

您需要能够查询父表吗

Parent.objects.all()
如果是,则很可能需要将多表继承与
abstract=False
一起使用

将模型继承与
abstract=False
一起使用,可以得到更复杂的数据库模式,以及更多的数据库关系。创建子实例将需要2次插入,而不是1次(父表和子表)。查询子数据将需要表联接。所以这种方法肯定有它的缺点。但当您想要查询公共列数据时,这是django中支持的最佳方式

Django多态性是在标准Django模型继承的基础上构建的,通过添加额外的列
polymorphic_ctype
,可以识别只有父对象的子类

使用
abstract=True
可以使用多种方法获得类似的结果。但它通常会导致更复杂的查询代码

如果使用
abstract=True
下面是两个示例,说明如何查询所有孩子的公共数据

  • 链接多个查询

    def query_all_childs(**kwargs):
        return chain(
            Child1.objects.filter(**kwargs)
            Child2.objects.filter(**kwargs)
        )
    
  • 使用数据库视图

    手动创建组合多个表的数据库视图(可以通过将sql代码附加到信号来实现):

    使用
    managed=False
    创建一个具体的父模型。这个标志告诉django在数据库迁移中忽略该表(因为我们已经为此手动创建了数据库视图)

    现在您可以查询
    CommonChild.objects.all()
    并访问子类的公共字段


说到性能,我不知道您的表有多大或读/写有多重,但很可能使用
abstract=False
不会显著影响您的性能。

为什么要使用django多态性?你的理由是什么?我喜欢这个图书馆,因为它为我解决了一些问题。它应该为您解决什么?我有很多类似的表,我想使用继承。我希望我的代码是简单的。我不想浏览5个不同的表,更改完全相同的字段。然而,我不希望sql查询速度太慢,但是看到这个包没有使用抽象字段,我不知道这会对我的性能产生什么影响。
create database view myapp_commonchild
select 'child1' as type, a, b from child1
union all
select 'child2' as type, a, b from child2
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