Django平均得分通过

时间:2014-06-24 19:52:27

标签: django

也许这是一个非常新手的问题,但我仍然坚持这一点。我不知道问题是模型还是我不太了解聚合和注释。

我有一个这样的模型:

class User(models.Model):
    collection   = models.ManyToManyField(Book, through='BookCollection')

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

class BookCollection(models.Model):
    user         = models.ForeignKey(User)
    book         = models.ForeignKey(Book)
    score        = models.IntegerField(default=0)

我希望获得所有图书和所有用户的平均分数,不包括那些默认分数等于0的分数(此值表示用户拥有该集合中的图书,但尚未评级) 。我正在尝试使用这样的注释:

Book.objects.exclude(collection__score=0).annotate(avg=Avg('collection__score'))

但是,如果有一本评分为0和3的图书,则会排除这两个条目。

有没有办法告诉Avg()它应该只考虑大于0的值?

提前致谢。

1 个答案:

答案 0 :(得分:1)

没有原始SQL,Django ORM无法做到这一点。

更好的模型是允许score字段中的空值。 Avg()中忽略空值:

class BookCollection(models.Model):
    ...
    score = models.IntegerField(null=True, blank=True, default=None)

None通常是描述字段中缺少条目的最佳方式。这避免了混淆,例如在计算中,例如计算平均值。