防止Django加入超类';桌子

防止Django加入超类';桌子,django,optimization,inheritance,model,django-queryset,Django,Optimization,Inheritance,Model,Django Queryset,具有非抽象父类的: class Animal(models.Model) 和两个子类: class Cow(Animal) class Dog(Animal) 和呼唤 Dog.objects.order_by('name') 查询数据库并返回连接的记录: SELECT ... FROM dog INNER JOIN animal ON (dog.animal_ptr_id = animal.id) ORDER BY dog.name ASC 然而,在我的例子中,“dog”不是一个表

具有非抽象父类的:

class Animal(models.Model)
和两个子类:

class Cow(Animal)
class Dog(Animal)
和呼唤

Dog.objects.order_by('name') 
查询数据库并返回连接的记录:

SELECT ... FROM dog 
INNER JOIN animal ON (dog.animal_ptr_id = animal.id) 
ORDER BY dog.name ASC
然而,在我的例子中,“dog”不是一个表,而是一个在数据库中定义的复杂视图。该视图已包含来自“animal”的所有必需字段,包括animal_ptr_____id可访问的动物id


如何防止django进行内部连接,从而大大降低查询速度?

我真的不明白为什么您认为在这种情况下,
dog
不是表,因为您没有使用抽象基类。因此,每个子类都有一个表

据我所知,避免多表继承的
内部联接的最佳方法是在
类Meta
中设置
abstract=True
。这似乎是你应该做的,但是

但是,如果坚持使用多表继承,则可以使用。类似的方法可能会奏效:

虽然
dog
表本身不会包含它从基类
Animal
继承的属性。为了获得这些继承的属性,我认为除非我错过了一些明显的东西,否则加入是不可避免的

然而,在我的例子中,“狗”不是一张桌子,而是一个复杂的视图 在数据库中定义

您需要为
狗设置
;否则,您将不使用视图,而是使用名为
app\u dog
(其中
app
是您的应用程序名称)的中间表


这会阻止django创建一个表,但使用一个内部定义的表(在您的例子中是视图)。请确保还指定了,并指定了。

我已经设置了表名,实际上我应该设置
managed=False
。但是这些并不能从查询中消除
内部联接
。在执行此操作之后,您是否进行了迁移或重新创建了数据库?我无权发出DDL查询。我正在为一个现有的数据库编写一个应用程序。我将使Animal成为一个抽象的基类。但是,动物由
模型(属性\ id、属性\值、动物\ id)引用,我使用
属性\集
访问它们。因此,我认为我需要使用非抽象动物来进行适当的外键查找。
dog
视图直接在数据库中定义,它还包含动物的所有属性。@tomasz如果定义“dog”在数据库中包含所有动物属性,然后你就可以像我提到的那样使用原始查询了。这看起来很有希望,但是我怎样才能使原始查询在模型管理器中充当查询集呢?我想我需要对db.models.sql.query.query子类化
并覆盖join\u map或其他一些字段,然后在我的自定义管理器中这样使用它:
def get\u query\u set(self):使用
时返回QuerySet(model=Dog,query=MyNoJoinQuery(model=Dog))
方法作为我获取的QuerySet
'RawQuerySet'对象没有属性'filter'
。我甚至不能将
extra()
RawQuerySet
s一起使用。
Dog.objects.raw('SELECT ... FROM myapp_dog ORDER BY dog.name ASC')