Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django从注释计数中排除_Python_Django_Django Models_Django Orm - Fatal编程技术网

Python Django从注释计数中排除

Python Django从注释计数中排除,python,django,django-models,django-orm,Python,Django,Django Models,Django Orm,本人有以下申请: from django.db import models class Worker(models.Model): name = models.CharField(max_length=60) def __str__(self): return self.name class Job(models.Model): worker = models.ForeignKey(Worker) is_completed = model

本人有以下申请:

from django.db import models


class Worker(models.Model):
    name = models.CharField(max_length=60)

    def __str__(self):
        return self.name


class Job(models.Model):
    worker = models.ForeignKey(Worker)
    is_completed = models.BooleanField()
我想用已完成作业的计数对Workers查询进行注释

我将尝试使用以下脚本执行此操作:

from myapp.models import Worker, Job
from django.db.models import Count

w = Worker.objects.create(name='Worker1')
Job.objects.create(worker=w, is_completed=False)
Job.objects.create(worker=w, is_completed=False)
Job.objects.create(worker=w, is_completed=True)
Job.objects.create(worker=w, is_completed=True)

workers = Worker.objects.all().annotate(num_jobs=Count('job'))
workers[0].num_jobs    
# >>> 4
workers = Worker.objects.all().exclude(job__is_completed=False).annotate(num_jobs=Count('job'))
# >>> []
最后一个查询的结果为空。如何从反向关系中排除元素

Django 1.8,python 2.7


UPD.我希望queryset中的所有工作人员,即使是那些没有工作的工作人员

更新:好的,我用这个来生成解决方案,我想我使用了:

条件表达式允许您在以下情况下使用。。。埃利夫。。。内在逻辑 过滤器、注释、聚合和更新。有条件的 表达式为表的每一行计算一系列条件 并返回匹配的结果表达式

注:(如@Pynchia所指出的
案例和
时的
)在Django 1.8中是新的

from django.db.models import IntegerField, Sum, Case, When

workers = Worker.objects.annotate(
              num_jobs=Sum(
                  Case(
                      When(job__is_completed=True, then=1),
                      default=0,  
                      output_field=IntegerField()
                  )
               )
           )
现在,每个工人将有一个num_jobs,它将是一个整数,显示工人有多少已完成的作业:)

如下

workers = Worker.objects.filter(job__is_completed=True)).annotate(num_jobs=Count('job__is_completed'))
注释至少完成一项作业的工人。 已完成作业计数为零的作业不包括在结果查询集中

如果您希望所有工作人员都出现在结果查询集中,那么如果我们能够编写

workers = Worker.objects.annotate(num_jobs=CountIf('job__is_completed', job__is_completed=True))
但不幸的是,我们不能。 因此,我在这里有点不知所措,我相信我的回答是片面的。 我欢迎一位比我更有能力的人介入,他可以对这件事有所了解

有关参考,请参见此(已关闭)

更新:Django 1.8引入了条件表达式@BogdiG的答案是使用这些新的运营商来解决这个问题。荣誉

更新

如果您需要每个工作人员的已完成作业计数,那么我们可以通过
.extra()
使用子查询:

Django现在支持Python映射条件表达式
SUM(CASE WHEN is_completed=True然后1 ELSE 0 END)
,语法如中所述



删除了有关过滤/排除的内容这里有两个选项。第一个是直接
Q
过滤器上的
Count

来自myapp.models导入工作者
从django.db.models导入计数,Q
workers=Worker.objects.annotate(
已完成的作业计数=计数(“作业”,过滤器=Q(作业已完成=真))
)
第二个是排除
Q
过滤器上的
Count
(有时需要排除,因为
Count
没有直接的
exclude
选项):

来自myapp.models导入工作者
从django.db.models导入计数,Q
workers=Worker.objects.annotate(
已完成的作业计数=计数(“作业”,过滤器=~Q(作业已完成=假))
)

我删除了我的答案,因为它不会返回所有工人,而只返回至少完成一项工作的工人。我相信你的解决方案也有同样的问题。我相信OP想用完成的工作数量注释所有工人,即使是零。@Pynchia我明白了,那么更新我的答案不是一个过滤器。我已经重新发布了我的答案,但我不确定它是否满足问题。如果OP澄清他/她是否希望结果查询中的所有员工我已经尝试过你的解决方案,但它不起作用,那就太好了。它似乎统计所有已完成或未完成的工作,并且不注释所有工人。请提供一个解释,说明它对example@Pynchia对我来说这很有效。你一定做错了什么。哇,太棒了!我现在不能玩它,但它看起来是向前迈进了一大步。我认为,在Django 1.8引入了条件表达式之后,当条件表达式是新的时,您应该提到
Case
,还有一件事:您确定需要
Q
操作符吗?根据中的示例,也许您可以去掉它并在(job_uis_completed=True,then=1)时使用
,…
docs@Pynchia是的,没有Q对象也可以工作,只是测试了一下。这个答案值得一读。显然,对所有记录进行注释并根据条件进行计数并不是那么简单
Worker.objects.extra(select={'jobs_done': 
     'SELECT COUNT(*) FROM {job_tbl} WHERE worker_id = {worker_tbl}.id AND is_completed'
     .format(worker_tbl=Worker._meta.db_table, job_tbl=Job._meta.db_table)})