2012-01-10 52 views
3

有没有什么办法从查询集中删除select相关的?Django。从查询集中删除select_related

我发现,django在count()操作中添加JOIN到sql查询。 所以,如果我们有这样的代码:

entities = Entities.objects.select_related('subentity').all() 
#We will have INNER JOIN here.. 
entities.count() 

我正在寻找一种方法,以消除加入。 一个重要的细节 - 我得到这个查询集Django的进入分页程序,所以我不能简单地写

Entities.objects.all().count() 

回答

1

你能告诉你需要这样的代码,我认为重构是这里最好的答案。

如果你想快速回答,entities.query.select_related = False,但它很hacky(如果你稍后需要select_related,不要忘记恢复该值)。

+1

我不认为我们的情况需要重构。简单情况 - 将实体列表插入分页程序中。在一个查询中使用count和inner join有点困惑,根本不需要它(相关表上没有过滤器)。谢谢你的回答。而已。 – 2012-01-10 12:58:35

+0

据我所知,通过给select_related提供一个参数,你在相关表上指定了一个过滤器(如果你没有为select_related()指定任何参数,它将获取所有相关对象,然后所有与这些对象相关的对象等递归)。 – 2012-03-29 21:43:39

1

我相信这个代码的注释提供了一个比较好的答案,一般的疑问,在这里问:

如果select_related(无)被调用时,列表会被清除。

https://github.com/django/django/blob/stable/1.8.x/django/db/models/query.py#L735

在一般意义上,如果你想要做的事到entities查询集,但首先从中取出select_related项目,entities.select_related(None)

但是,这可能无法解决您与paginator的特定情况。如果你做entries.count(),那么它已经将删除select_related项目。如果你发现自己有额外的JOIN发生,那么它可能是几个非理想的因素。可能是ORM无法删除它,因为其他逻辑可能会或可能不会影响与select_related结合的计数。

作为其中一个非理想情况的简单示例,请考虑Foo.objects.select_related('bar').count()Foo.objects.select_related('bar').distinct().count()。您可能很明显知道原始查询集不包含多个条目,但对于Django ORM并不明显。因此,执行的SQL包含一个JOIN,并且没有解决该问题的通用处方。即使应用.select_related(None)也不会帮助你。