好的,现在问题包括模型定义,我向您提出这应该可行,除非您的 Django 版本不支持我在这里使用的某些功能(在这种情况下,请告诉我!):
Post.objects.filter(thread__in=thread_set, status='active').aggregate(num_posts=Count('id'))
Django 允许__in
过滤器采用 QuerySet 来决定要做什么IN
子句应该类似于 SQL,所以如果你通过thread__in=thread_set
,Django 将过滤帖子,以便仅那些thread
字段指向其中之一id
你的线程数thread_set
留下来为aggregate
打电话来看看。
这应该过滤帖子只需一个数据库查询与类似的东西WHERE thread_id IN ...
在内部,而不是每个线程一个查询,这确实是可怕的。如果发生其他事情,这将是 Django 中的一个错误......
结果应该是最多两个查询来建立Category
的帖子计数-- 获得之一thread_set
另一个实际上是用来计算帖子数的。另一种方法是根据以下条件过滤线程/后连接Thread
's category
场和Post
's status
场,我不一定期望会那么快。 (我说“最多”,因为我猜它们可以自动融合......尽管我不认为当前的 Django 会发生这种情况。抱歉,无法检查 ATM。)
EDIT: Django 的 QuerySet API 参考 http://docs.djangoproject.com/en/dev/ref/models/querysets/说这个__in
过滤器:
IN
在给定的列表中。
Example:
Entry.objects.filter(id__in=[1, 3, 4])
SQL 等效项:
SELECT ... WHERE id IN (1, 3, 4);
您还可以使用查询集动态评估值列表,而不是提供文字值列表:
inner_qs = Blog.objects.filter(name__contains='Cheddar')
entries = Entry.objects.filter(blog__in=inner_qs)
该查询集将被评估为子选择语句:
SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
上面的代码片段也可以写成如下:
inner_q = Blog.objects.filter(name__contains='Cheddar').values('pk').query
entries = Entry.objects.filter(blog__in=inner_q)
Django 1.1 中的更改:在Django 1.0中,只有后一段代码是有效的。
第二种形式的可读性较差并且编写起来不自然,因为它访问内部查询属性并需要 ValuesQuerySet。如果您的代码不需要与 Django 1.0 兼容,请使用第一种形式,直接传入查询集。
所以我猜姜戈is能够通过单个查询到这里有问题的情况下的数据库。如果数据库的查询分析器做得很好,效果可能非常接近最佳。 :-)