You can use aggregate() and annotate() with Avg() to average the prices in Product
model and category by category as shown below. *You need to use order_by('pk')
with annotate()
otherwise values are printed in descending order:
from django.db.models import Avg
# Average the prices in "Product" model
print(
"<All products>",
Product.objects.aggregate(Avg('price'))
)
print()
# Average the prices in "Product" model category by category
for obj in Category.objects.all():
print(
obj.id, obj.name,
Product.objects.filter(category=obj)
.aggregate(Avg('price'))
)
print()
# Average the prices in "Product" model category by category
for obj in Category.objects.all():
print(
obj.id, obj.name,
obj.product_set.aggregate(Avg('price'))
)
print()
# Average the prices in "Product" model category by category
qs = Category.objects.annotate(Avg('product__price')).order_by('pk')
for obj in qs:
print(obj.id, obj.name, obj.product__price__avg)
Then, these below are outputted on console:
<All products> {'price__avg': Decimal('20.1578947368421053')}
1 Fruits {'price__avg': Decimal('13.5714285714285714')}
2 Vegetable {'price__avg': Decimal('23.0000000000000000')}
3 Meat {'price__avg': Decimal('24.2500000000000000')}
4 Fish {'price__avg': Decimal('25.3333333333333333')}
1 Fruits {'price__avg': Decimal('13.5714285714285714')}
2 Vegetable {'price__avg': Decimal('23.0000000000000000')}
3 Meat {'price__avg': Decimal('24.2500000000000000')}
4 Fish {'price__avg': Decimal('25.3333333333333333')}
1 Fruits 13.5714285714285714
2 Vegetable 23.0000000000000000
3 Meat 24.2500000000000000
4 Fish 25.3333333333333333
And, you can change the default key price__avg
and product__price__avg
to priceAvg
for price column as shown below:
from django.db.models import Avg
# Average the prices in "Product" model
print(
"<All products>",
Product.objects.aggregate(priceAvg=Avg('price'))
) # ↑ Here
print()
# Average the prices in "Product" model category by category
for obj in Category.objects.all():
print(
obj.id, obj.name,
Product.objects.filter(category=obj)
.aggregate(priceAvg=Avg('price'))
) # ↑ Here
print()
# Average the prices in "Product" model category by category
for obj in Category.objects.all():
print(
obj.id, obj.name,
obj.product_set.aggregate(priceAvg=Avg('price'))
) # ↑ Here
print()
# Average the prices in "Product" model category by category
qs = Category.objects.annotate(priceAvg=Avg('product__price')).order_by('pk')
for obj in qs: # ↑ Here
print(obj.id, obj.name, obj.priceAvg)
# ↑ Here
Then, the default key is changed as shown below:
<All products> {'priceAvg': Decimal('20.1578947368421053')}
1 Fruits {'priceAvg': Decimal('13.5714285714285714')}
2 Vegetable {'priceAvg': Decimal('23.0000000000000000')}
3 Meat {'priceAvg': Decimal('24.2500000000000000')}
4 Fish {'priceAvg': Decimal('25.3333333333333333')}
1 Fruits {'priceAvg': Decimal('13.5714285714285714')}
2 Vegetable {'priceAvg': Decimal('23.0000000000000000')}
3 Meat {'priceAvg': Decimal('24.2500000000000000')}
4 Fish {'priceAvg': Decimal('25.3333333333333333')}
1 Fruits 13.5714285714285714
2 Vegetable 23.0000000000000000
3 Meat 24.2500000000000000
4 Fish 25.3333333333333333