gpt4 book ai didi

Django Querysets - 在 .extra() 之后使用 .annotate()

转载 作者:行者123 更新时间:2023-12-01 03:43:54 26 4
gpt4 key购买 nike

假设我有一个非常简单的模型,如下所示:

class Test(models.Model):
category = models.CharField(unique=True)
start_time = models.DateTimeField()
end_time = models.DateTimeField()

基本上,我想使用 Django 的 ORM API 来获取每个类别的平均持续时间。 SQL 查询将如下所示:
SELECT category, AVG(end_time - start_time) AS avg_duration
FROM test_table
GROUP BY category

我尝试使用以下代码,但根据文档,.annotate() 中的 F() 表达式仅在 Djano 1.8 中可用。
Test.objects.values('category', 'start_time', 'end_time').annotate(avg_duration=Avg(F(end_time) - F(start_time))

我也尝试过像这样使用 .extra(),但我得到了一个 FieldError。
Test.objects.extra(select={'duration':'end_time - start_time'}).values('category', 'duration').annotate(avg_duration=Avg('duration'))

从表面上看,第二次尝试表明 annotate 函数无法解析列别名。真的是这样,还是我错过了什么?

此外,除了使用 Django 1.8 和/或使用原始 SQL 创建一个存储派生信息(每个条目的持续时间)的附加列之外,你们还能推荐哪些其他替代方案?任何帮助将不胜感激。谢谢!

最佳答案

尝试这个:

Test.objects.values('category').extra(select={'avg_duration':'AVG(end_time - start_time)'})

是的,这不会发生,因为

Any extra() call made after a values() call will have its extra selected fields ignored.



之前不能用 .values()或者,因为您将被迫将其包含在 .values() 中。 :

If you use a values() clause after an extra() call, any fields defined by a select argument in the extra() must be explicitly included in the values() call.



所以这样任何 .extra选择将被包括 in the grouping .

但是你也不能做出这样的 Avg没有 .extra所以我认为剩下的唯一解决方案是使用 .raw
Test.objects.raw('\
SELECT id, category, AVG(end_time - start_time) AS avg_duration \
FROM test_table \
GROUP BY category'
)

关于Django Querysets - 在 .extra() 之后使用 .annotate(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28764381/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com