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代码附加到信号来实现):
使用
创建一个具体的父模型。这个标志告诉django在数据库迁移中忽略该表(因为我们已经为此手动创建了数据库视图) 现在您可以查询managed=False
并访问子类的公共字段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