防止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')