如何向 Django QuerySet 添加附加列
Posted
技术标签:
【中文标题】如何向 Django QuerySet 添加附加列【英文标题】:How to add additional column to Django QuerySet 【发布时间】:2014-10-08 03:37:11 【问题描述】:我有一个带有 Books 的 QuerySet,我想在每个 Book 结果中添加一个 score
字段。
qs = Book.objects.all()
在原始 SQL 中我会写:
SELECT
*,
(
(SELECT COUNT(*) FROM votes WHERE value=1 AND book=b.id) -
(SELECT COUNT(*) FROM votes WHERE value=-1 AND book=b.id)
) AS score
FROM
Book b;
如何在 Django 中实现它?我试过annotate()
,但它似乎不适合这种东西。
【问题讨论】:
将annotate
或extra
与select
一起使用(在此处提问之前请更仔细地使用google)。
看看docs.djangoproject.com/en/dev/topics/db/aggregation/…
谷歌中没有一个页面可以描述我想要的。我已经在文档中阅读了有关 annotate
和 extra
的所有内容。对此它只字未提。如果您设法找到任何有用的东西,请分享一个链接。
@ambi 如何在这里过滤任何帮助?
【参考方案1】:
原始 SQL 不是唯一的方法。您可以使用Value()
表达式(参见文档here):
from django.db.models import CharField, Value
MyModel.objects.all().annotate(mycolumn=Value('xxx', output_field=CharField()))
【讨论】:
太棒了,我正在找这个 给出错误:未为 output_field 定义全局名称“IntegerField” 您需要像往常一样导入IntegerField。【参考方案2】:如果投票的可能值只有 1 和 -1,您可以使用提到的 annotate:Book.objects.annotate(score=Sum('votes__value'))
将它们相加。
如果有更多可能的值,您可以通过在上述查询中添加.filter(votes__value__range=(1,1))
来过滤注释。
如果它更复杂,您将不得不使用 extra
和 select
。
【讨论】:
谢谢。添加另一列不能用于Sum
、Avg
和类似的列怎么样?如果我们想添加一些格式化文本或布尔列怎么办? annotate(mycolumn='xxx')
不起作用。
您应该在这里使用extra
和select
,如下所述:docs.djangoproject.com/en/1.7/ref/models/querysets/#extra
所以,原始 SQL 是唯一的方法 :( 感谢您的帮助以上是关于如何向 Django QuerySet 添加附加列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用附加过滤的相关对象作为 Django 中的字段来获取结果?