Django 中的条件注释

发布于 2024-09-16 15:08:29 字数 480 浏览 9 评论 0原文

我得到了简单的要求(不是简单的实现),并弄清楚如何在不多次命中数据库且查询集中没有 .extra() 的情况下实现它。

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

Project:
  name = xxx
  code = xxx

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

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

我可以通过注释获取total_tasks,但不能Completed_tasks,因为它需要注释中的条件。有办法做吗?

I got simple requirement (not simple implementation), and figuring out how to achieve it without making multiple hits to db, and without .extra() in queryset.

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

Project:
  name = xxx
  code = xxx

Projects contain Tasks which got various statuses. (Assume status=3 is Completed)
Now, I want to list out all projects with their total tasks and completed tasks, like below

  1. Project 1, total_tasks=5, completed_tasks=2
  2. Project 1, total_tasks=2, completed_tasks=1

I am able to get total_tasks with annotate, but not completed_tasks, since it required condition in annotation. Is there anyway to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

奢欲 2024-09-23 15:08:29

此功能是 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()

This feature is new in Django 1.8.

Refer to: https://docs.djangoproject.com/en/1.8/ref/models/conditional-expressions/

This is a possibility:

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()
椒妓 2024-09-23 15:08:29

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

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

I don't know if it will help, but you can write your own custom annotation objects. I've just done it though without the conditional part. I based my solution on this link:
http://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django

but didn't use the example there. Instead I looked at the django code for aggregates and extended the Sum and Count objects themselves.

梦途 2024-09-23 15:08:29

如果您不介意额外的查询,则可以派生两个查询集而不是一个。第一个可以获取总计数,第二个可以过滤 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'))

If you do not mind additional queries, you can derive two querysets instead of one. The first can get you the total count and the second can filter on tasks_status and thereby get you the completed count.

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'))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文