Django:只计算带有annotate()&的非空CharField。值()

时间:2014-05-25 07:54:47

标签: django django-models django-queryset django-aggregation

Django recommends未在null上使用CharField,但是注释包含计数中的空字符串。有没有办法避免这种情况而不排除查询中带有空字符串的行?

我的问题并不是如何实现我的查询,但从根本上说,应该注释/聚合计数是否包括空字段。 Django认为空为基于字符串的字段的NULL替换。

我的模特:

class Book(models.Model):
    name = models.CharField(...)

class Review(models.Model):
    book = models.ForeignKey()
    category = models.ForeignKey()
    review = models.CharField(max_length=200, default='', blank=True)

计算非空评论&按类别分组,我使用

Review.objects.values('category').annotate(count=Count('review'))

这不起作用,因为注释也会计算空值(如果条目为NULL,则不会这样做)。我可以在注释调用之前过滤掉空字符串,但我的查询更复杂,我需要所有空的&非空对象。

是否有一种更聪明的方法可以使用注释并跳过空值或者我应该从

更改模型
review = models.CharField(max_length=200, default='', blank=True)

review = models.CharField(max_length=200, default=None, blank=True, null=True)

2 个答案:

答案 0 :(得分:1)

我遇到了非常相似的情况。我使用 Conditional Expressions 解决了它:

review_count = Case(
    When(review='', then=0),
    default=1,
    output_field=IntegerField(),
)
Review.objects.values('category').annotate(count=review_count)

答案 1 :(得分:0)

  

......我需要所有空的&非空对象。

使用values时没有任何意义。您将获得仅包含categorycount键的字典列表,而不是实际对象。除count中的不同数字外,您还会看到过滤掉空review值之间没有区别。最重要的是,您可以过滤一本书(id=2),并且可以预期可以有多个评论。

您需要认真重新思考您正在尝试做什么,以及您的模型定义如何适应这一点。