41👍
✅
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.
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
- Specific way of requiring one of two fields in django model definition
- Google App Engine Application Extremely slow
Source:stackexchange.com