如何从Django中的一组对象中获得平均值?

yzuktlbb  于 2023-01-31  发布在  Go
关注(0)|答案(2)|浏览(151)

我有一个简单的评级系统的财产。你给予它一个标记出5(星)。模型是这样定义的

def Property(models.Model)
    # stuff here

def Rating(models.Model)
    property = models.ForeignKey(Property)
    stars = models.IntegerField()

我想做的是得到一个属性,找到所有的评级对象,收集它们,然后从它们那里得到平均的“星级”。
有什么办法吗?

u4vypkhs

u4vypkhs1#

您应该使用Aggregation(doc)

from django.db.models import Avg

p = Property.objects.get(...)
stars_average = p.rating_set.aggregate(Avg('stars')).values()[0]

但我对我的例子有点不确定。

jtjikinw

jtjikinw2#

您可以将aggregate()和annotate()与Avg()一起使用,以按属性计算Rating模型中的星级平均值,如下所示。* 我需要将order_by('pk')annotate()一起使用,否则值将按降序打印:

from django.db.models import Avg

# Average the stars in "Rating" model
print(Rating.objects.aggregate(Avg('stars'))) 

print()

# Average the stars in "Rating" model property by property
for obj in Property.objects.all(): 
    print(
        Rating.objects.filter(property=obj)
                      .aggregate(Avg('stars'))
    )

print()

# Average the stars in "Rating" model property by property
for obj in Property.objects.all(): 
    print(obj.rating_set.aggregate(Avg('stars')))

print()

# Average the stars in "Rating" model property by property
qs = Property.objects.annotate(Avg('rating__stars')).order_by('pk')
for obj in qs:
    print(obj.rating__stars__avg)

然后,在控制台上输出以下内容:

{'stars__avg': 3.7}

{'stars__avg': 3.2}
{'stars__avg': 3.6}
{'stars__avg': 4.0}

{'stars__avg': 3.2}
{'stars__avg': 3.6}
{'stars__avg': 4.0}

3.2
3.6
4.0

并且,您可以将stars列的默认键stars__avg更改为starsAvg,如下所示:

from django.db.models import Avg

# Average the stars in "Rating" model
print(Rating.objects.aggregate(starsAvg=Avg('stars'))) 
                               # ↑ Here
print()

# Average the stars in "Rating" model property by property
for obj in Property.objects.all(): 
    print(
        Rating.objects.filter(property=obj)
                      .aggregate(starsAvg=Avg('stars'))
    )                            # ↑ Here

print()

# Average the stars in "Rating" model property by property
for obj in Property.objects.all(): 
    print(obj.rating_set.aggregate(starsAvg=Avg('stars')))
                                   # ↑ Here
print()

# Average the stars in "Rating" model property by property
qs = Property.objects.annotate(starsAvg=Avg('rating__stars')).order_by('pk')
for obj in qs:                 # ↑ Here
    print(obj.starsAvg)
              # ↑ Here

然后,默认密钥更改如下:

{'starsAvg': 3.7}

{'starsAvg': 3.2}
{'starsAvg': 3.6}
{'starsAvg': 4.0}

{'starsAvg': 3.2}
{'starsAvg': 3.6}
{'starsAvg': 4.0}

3.2
3.6
4.0

相关问题