Django模型:聚合不直接相关的模型

时间:2018-04-07 01:10:38

标签: django django-models

我有以下模特:

class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
some_field = models.CharField(max_length=100)


class UserRating(models.Model):
subject_user = models.ForeignKey(User, related_name='rated_user', on_delete=models.CASCADE)
rating_user = models.ForeignKey(User, related_name='rating_user', on_delete=models.CASCADE)
rating = models.IntegerField()

    class Meta:
        unique_together = ("subject_user", "rating_user")

我正在尝试在UserRating模型中获取所有UserProfiles的查询集,其中包含带注释的平均值。

我尝试过以下操作:

    queryset = UserProfile.objects.all()
    for profile in queryset:
        user = profile.user
        ratingset = UserRating.objects.filter(subject_user = user).values_list('rating')
        if len(ratingset) == 0:
            profile.rating = 0
        else:
        profile.rating = sum(ratingset) / float(len(ratingset))

然而,这会引发以下错误:

TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

我考虑通过迭代评级集来计算总和,但我的方法似乎有点矫枉过正。有没有更简单的方法来实现这个目标?

1 个答案:

答案 0 :(得分:0)

Django实际上提供了各种直接通过SQL聚合的方法,效率更高。这应该完成工作:

profiles_with_ratings = UserProfile.objects.annotate(rating=Avg('user__rated_user__rating'))

这里的文档:https://docs.djangoproject.com/en/2.0/topics/db/aggregation/

旁注:您实际拥有的是由于某种原因您手动构建的用户之间的多对多关系。