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

发布于 2024-08-30 00:39:42 字数 286 浏览 7 评论 0原文

我有一个简单的房产评级系统。您给它打分,满分 5 分(星)。模型的定义如下:

def Property(models.Model)
    # stuff here

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

我想要做的是获取一个属性,找到所有评级对象,收集它们,然后从中获取平均“星星”。

有什么想法如何做到这一点?

I have a simple rating system for a property. You give it a mark out of 5 (stars). The models are defined like this

def Property(models.Model)
    # stuff here

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

What I want to do is get a property, find all the Rating objects, collect them, then get the average 'stars' from them.

Any ideas how to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浸婚纱 2024-09-06 00:39:42

您应该使用 Aggregation(doc)

from django.db.models import Avg

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

有点不确定我的例子虽然。

You should use Aggregation(doc):

from django.db.models import Avg

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

A little bit unsure about my example though.

逆流 2024-09-06 00:39:42

您可以使用 aggregate()annotate() 与 < a href="https://docs.djangoproject.com/en/4.1/ref/models/querysets/#avg" rel="nofollow noreferrer">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

You can use aggregate() and annotate() with Avg() to average the stars in Rating model and property by property as shown below. *I need to use order_by('pk') with annotate() otherwise values are printed in descending order:

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)

Then, these below are outputted on console:

{'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

And, you can change the default key stars__avg for stars column to starsAvg as shown below:

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

Then, the default key is changed as shown below:

{'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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文