6

我得到了简单的要求(不是简单的实现),并弄清楚如何在不多次访问 db 和查询集中的情况下实现它.extra()

Task:
  name = xxx
  status = models.IntegerField(choices=some_choices)
  project = ForeignKey(Project)

Project:
  name = xxx
  code = xxx

项目包含获得各种状态的任务。(假设 status=3 已完成)现在,我想列出所有项目及其总任务和已完成任务,如下所示

  1. 项目 1,total_tasks=5,completed_tasks=2
  2. 项目 1,total_tasks=2,completed_tasks=1

我能够获得带有注释的total_tasks,但不能获得completed_tasks,因为它需要注释中的条件。有什么办法吗?

4

3 回答 3

9

此功能是Django 1.8 中的新功能。

参考:https ://docs.djangoproject.com/en/1.8/ref/models/conditional-expressions/

这是一种可能:

from django.db.models.aggregates import Count
from django.db.models.expressions import F, Value, Case, When

projects = Project.objects.annotate(
        total_tasks=Count('task__pk'),
        completed_tasks=Count(Case(
           When(status=3, then=F('task__pk')),
           output_field=IntegerField()
        ))).all()
于 2015-10-20T18:12:46.750 回答
0

我不知道它是否会有所帮助,但您可以编写自己的自定义注释对象。尽管没有条件部分,但我刚刚完成了它。我的解决方案基于此链接: http ://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django

但没有使用那里的例子。相反,我查看了聚合的 django 代码并扩展了 Sum 和 Count 对象本身。

于 2010-09-02T20:16:46.220 回答
0

如果您不介意额外的查询,您可以派生两个查询集而不是一个。第一个可以让你得到总计数,第二个可以过滤tasks_status,从而让你得到完整的计数。

from django.db.models import Count
all_projects = Project.objects.all()
total_counts = all_projects.annotate(count = Count('tasks'))
completed_counts = all_projects.filter(tasks_status = 3).annotate(count = Count('tasks'))
于 2010-08-31T09:46:06.060 回答