【问题标题】:Count and OR clause in a Django querysetDjango 查询集中的计数和 OR 子句
【发布时间】:2012-10-01 07:29:24
【问题描述】:

我有一个不符合预期的非常简单的查询。

# Retrieve news                                                               
news = News.objects.filter(available=True)                                    
if area:                                                                      
    news = news.annotate(Count('areas')).filter(Q(areas__count=0)
                                                |Q(areas=area))

我希望有没有受影响区域或指定区域的新闻。但我一个都没有。

当我打印我得到的查询时:

SELECT "chimere_news"."id", "chimere_news"."title", 
       "chimere_news"."available","chimere_news"."date", "chimere_news"."content",
       COUNT("chimere_news_areas"."area_id") AS "areas__count"
FROM "chimere_news"
LEFT OUTER JOIN "chimere_news_areas" ON ("chimere_news"."id" = "chimere_news_areas"."news_id")
LEFT OUTER JOIN "chimere_news_areas" T4 ON ("chimere_news"."id" = T4."news_id")
WHERE ("chimere_news"."available" = True  AND (T4."area_id" = 1 ))
GROUP BY "chimere_news"."id", "chimere_news"."title", "chimere_news"."available", 
"chimere_news"."date", "chimere_news"."content"
HAVING COUNT("chimere_news_areas"."area_id") = 0

我做错了什么还是 Django 错误?

【问题讨论】:

  • Areas 是 News 中的 ManyToManyField?
  • 是的,它是(实际上是ManyToManyField的一个子类,为了改变widget)
  • 我可以看到一个明显的问题是areas=area。你应该使用areas_in=[area.id]。其次,你可以注释c=Count('areas')而不是使用areas__count=0并使用它吗?
  • areas=area 通常不会造成问题。我试图按照您的建议明确表达,但效果并不好。事实是 2 个子句 Q(areas__count=0) 和 Q(areas=area) 单独工作正常。

标签: django django-queryset


【解决方案1】:

如果您只需要将计数与零进行比较,请尝试改用 isnull

if area:                                                                      
    news = news.filter(Q(areas__isnull=True)|Q(areas=area))

【讨论】:

  • 它有效。谢谢!我仍然不知道我的第一段代码是否显示了我应该报告的 Django 错误,但我现在使用这个解决方案。
  • 很高兴它成功了!我认为您可能在初次尝试时遇到了this issue(或至少类似的东西)。
  • 确实这似乎与这个问题有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多