Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make an average from values of a foreign key in Django?

I have a book model and a review model like this in Django:

class Book(models.Model):

    ratings = models.FloatField()


class Review(models.Model):
    book = models.ForeignKey(
        Book,
        on_delete=models.CASCADE,
        related_name='reviews',
    )
    review = models.CharField(max_length=5000)
    score = models.PositiveSmallIntegerField(null=True, blank=True,
                                             validators=[MinValueValidator(0), MaxValueValidator(10)])

How can I create a method in Book to calculate the ratings (which is the average from all Reviews associated to a specific book)?


1 Answers

You can implement a property like:

from django.db.models import Avg

class Book(models.Model):

    @property
    def ratings(self):
        return self.reviews.aggregate(avg_score=Avg('score'))['avg_score']

Or if you need to do this in bulk, you can annotate your queryset:

from django.db.models import Avg

Book.objects.annotate(
    avg_rating=Avg('reviews__score')
)

Book objects that arise from this queryset, will have an extra attribute avg_rating, that contains the average of the score of the related Reviews.

like image 134
Willem Van Onsem Avatar answered Dec 23 '25 17:12

Willem Van Onsem