Kev*_*ker 46 django abstract-class
假设我有一个如下所示的抽象基类:
class StellarObject(BaseModel):
title = models.CharField(max_length=255)
description = models.TextField()
slug = models.SlugField(blank=True, null=True)
class Meta:
abstract = True
Run Code Online (Sandbox Code Playgroud)
现在,假设我有两个从StellarObject继承的实际数据库类
class Planet(StellarObject):
type = models.CharField(max_length=50)
size = models.IntegerField(max_length=10)
class Star(StellarObject):
mass = models.IntegerField(max_length=10)
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.如果我想获得行星或星星,我所做的就是:
Thing.objects.all() #or
Thing.objects.filter() #or count(), etc...
Run Code Online (Sandbox Code Playgroud)
但是如果我想获得所有StellarObjects呢?如果我做:
StellarObject.objects.all()
Run Code Online (Sandbox Code Playgroud)
它当然会返回错误,因为抽象类不是实际的数据库对象,因此无法查询.我读过的所有内容都说我需要做两个查询,一个是行星和星星,然后合并它们.这似乎非常低效.这是唯一的方法吗?
Dan*_*man 38
从根本上说,这是对象和关系数据库之间不匹配的一部分.ORM在抽象差异方面做得很好,但有时你只是反对它们.
基本上,您必须在抽象继承之间进行选择,在这种情况下,两个类之间不存在数据库关系,或多表继承,这会使数据库关系以每个查询的效率(额外的数据库连接)为代价.
Zlo*_*erg 10
您无法查询抽象基类.对于多表继承,您可以使用django-model-utils
它InheritanceManager
,它QuerySet
使用select_subclasses()
方法扩展标准,它正确地执行您需要:它左连接所有继承的表并为每一行返回适当的类型实例.
这是模型中多态性的一个示例(多态性 - 一种的多种形式)。
为了一两个地方的一些 if-else 代码,只需手动处理它 - 在开发/维护方面可能会更快更清晰(即可能值得,除非这些查询受到严重打击您的数据库 - 这是您的判断,取决于具体情况)。
幸运的是,有一个库可以处理django 中的多态性,django-polymorphic - 这些文档将向您展示如何精确地做到这一点。正如您所描述的那样,这可能是直接查询的“正确答案”,特别是如果您想在很多地方进行模型继承。
这种类型具有上述两种类型的缺点,但我过去曾成功地使用它自动将多个查询集的所有压缩在一起,同时保留了一个包含两种类型模型的查询集对象的好处。
查看django-querysetsequence,它管理多个查询集的合并。
它不像 那样受支持或稳定django-polymorphic
,但仍然值得一提。
归档时间: |
|
查看次数: |
12405 次 |
最近记录: |