python - 使用带注释的字段执行 groupby 计数的问题
问题描述
语境
我有一个名为Article的表/模型。
在这个模型中,我有几个字段,例如到期日期、可见性和状态。这些字段确定是否应显示文章。本质上,所需的逻辑是这样的:
display = True
if status == 'Private'; display = False
if visibility == False; display = False
...
为了简单起见,在这篇文章中,我将只使用一个字段:status
. 该status
字段是 a CharField
,选择为'Private'
或'Public'
。
为了制定显示逻辑,我使用注释。这个比较简单:
all_articles = Article.objects.annotate(
display=Case(When(status='Private', then=Value(False)), default=Value(True), output_field=models.BooleanField())
)
displayed_articles = all_articles.filter(display=True)
notdisplayed_articles = all_articles.filter(display=False)
目标
有了这个设置,我想使用 Django ORM 来执行 group by 计数,以确定有多少文章正在显示,有多少没有。
结果会像这样以 SQL 表格格式显示:
展示 | 数数 |
---|---|
真的 | 500 |
错误的 | 2000 |
问题
这是实现我的目标的自然方式:
queryset = Article.objects.annotate(
display=Case(
When(status='Private', then=Value(False)), default=Value(True), output_field=models.BooleanField()
)
).values('display').annotate(count=Count('id')).order_by()
print(queryset)
期待
我期待这样的事情:
<QuerySet [{'display': True, 'count': 500}, {'display': False, 'count': 2000}]>
错误
但是,我得到了这个:
django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Column 'blog_article.status' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. (8120) (SQLExecDirectW)")
为什么会发生这种情况,我该如何解决?
调查 SQL 查询
我通过以下方式查看了生成的 SQL 查询:
print(queryset.query)
SELECT CASE
WHEN [blog_article].[status] = Private THEN False
ELSE True
END AS [display],
COUNT_BIG([blog_article].[id]) AS [count]
FROM [blog_article]
GROUP BY CASE
WHEN [blog_article].[status] = Private THEN False
ELSE True
END
查询的一般结构看起来不错,我只需要对其进行一些小改动。以下查询已针对数据库成功执行。
SELECT CASE
WHEN [faq_faq].[status_type] = 'Private' THEN 0
ELSE 1
END AS [display],
COUNT_BIG([faq_faq].[id]) AS [count]
FROM [faq_faq]
GROUP BY CASE
WHEN [faq_faq].[status_type] = 'Private' THEN 0
ELSE 1
END
我还测试了使用 运行此查询pyodbc
,并且已成功执行。