相关疑难解决方法(0)

带有嵌套过滤器的Django注释

是否可以在注释中进行过滤?

在我看来这样的事情(实际上并不起作用)

Student.objects.all().annotate(Count('attendance').filter(type="Excused"))

由此产生的表格将让每个学生都有理由缺席.查看文档过滤器只能在注释之前或之后进行,否则将无法产生所需的结果.

解决方法就是这样

for student in Student.objects.all():
    student.num_excused_absence = Attendance.objects.filter(student=student, type="Excused").count()
Run Code Online (Sandbox Code Playgroud)

这可以工作,但在实际应用程序中执行很多查询,这可能会变得不切实际.我认为这种类型的语句在SQL中是可行的,但如果可能的话,我更愿意继续使用ORM.我甚至尝试过两个单独的查询(一个用于所有学生,另一个用于获得总数)并将它们与|组合.组合改变了总数:(

阅读答案和评论后的一些想法

我在这里使用额外的SQL解决了出勤问题.

  • 蒂米的博客文章很有用.我的答案是基于它的.
  • hash1baby的答案有效,但似乎与sql一样复杂.它还需要执行sql然后在for循环中添加结果.这对我不好,因为我将大量这些过滤查询堆叠在一起.我的解决方案构建了一个包含大量过滤器和额外的大型查询集,并立即执行所有操作.
  • 如果性能没有问题 - 我建议for循环工作.到目前为止,这是最容易理解的.

django

20
推荐指数
2
解决办法
8538
查看次数

django annotate and count:如何过滤要包括在count中的那些

给定一个查询集,我用以下内容添加相关对象(ModelA)的计数:

qs = User.objets.all()
qs.annotate(modela__count=models.Count('modela'))
Run Code Online (Sandbox Code Playgroud)

但是,有没有办法计算只满足标准的ModelA?例如,计算ModelA,其中deleted_at为null?

我尝试了两种不能正常工作的解决方案.

1)正如@knbk建议的那样,在注释之前使用过滤器.

qs = User.objects.all().filter(modela__deleted_at__isnull=True).annotate(modela__count=models.Count('modela', distinct=True))
Run Code Online (Sandbox Code Playgroud)

这是django生成的查询的简化版本:

SELECT COUNT(DISTINCT "modela"."id") AS "modela__count", "users".*
FROM "users"
LEFT OUTER JOIN "modela" ON ( "users"."id" = "modela"."user_id" ) 
WHERE "modela"."deleted_at" IS NULL 
GROUP BY "users"."id"
Run Code Online (Sandbox Code Playgroud)

问题来自WHERE子句.实际上,有一个LEFT JOIN,但后来的WHERE条件迫使它成为一个简单的JOIN.我需要将条件提升到JOIN子句中,以使其按预期工作.

所以,而不是

LEFT OUTER JOIN "modela" ON ( "users"."id" = "modela"."user_id" ) 
WHERE "modela"."deleted_at" IS NULL
Run Code Online (Sandbox Code Playgroud)

当我在纯SQL中直接执行它时,我需要以下内容.

LEFT OUTER JOIN "modela" ON ( "users"."id" = "modela"."user_id" ) 
AND "modela"."deleted_at" IS NULL
Run Code Online (Sandbox Code Playgroud)

如何在不执行原始查询的情况下更改查询集以获取此值?

2)正如其他人所说,我可以使用条件聚合.

我尝试了以下方法:

qs = User.objects.all().annotate(modela__count=models.Count(Case(When(modela__deleted_at__isnull=True, then=1))))
Run Code Online (Sandbox Code Playgroud)

变成以下SQL查询:

SELECT COUNT(CASE …
Run Code Online (Sandbox Code Playgroud)

django django-models django-queryset

17
推荐指数
1
解决办法
1万
查看次数

如何修复 Django annotate() 引发的 AttributeError: 'WhereNode' 对象没有属性 'select_format'?

关于 SO 有很多类似的问题,但是这个特定的错误消息没有出现在我的任何搜索中:

AttributeError: 'WhereNode' object has no attribute 'select_format'
Run Code Online (Sandbox Code Playgroud)

当尝试使用annotate()比较(布尔)结果的 Django 查询集时会引发此问题,例如以下简化示例中的gt 查找:

Score.objects.annotate(positive=Q(value__gt=0))
Run Code Online (Sandbox Code Playgroud)

该模型如下所示:

class Score(models.Model):
    value = models.FloatField()
    ...
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题?

python django django-queryset

7
推荐指数
1
解决办法
1670
查看次数

标签 统计

django ×3

django-queryset ×2

django-models ×1

python ×1