Reputation: 4512
I'm building a sample django app and I can't aggregate properly some sql results.
Consider these 3 models:
Movie model
class Movie(models.Model):
source_id = models.CharField(max_length=100, primary_key=True)
title = models.CharField(max_length=200, validators=[MinLengthValidator(1)])
Rating model
class Rating(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
rating = models.PositiveIntegerField()
username = models.CharField(max_length=100, validators=[MinLengthValidator(1)])
Comment model
class Comment(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
username = models.CharField(max_length=100, validators=[MinLengthValidator(1)])
body = models.TextField()
Then consider the following mysql tables:
movie
+-----------+-----------+
| source_id | title |
+-----------+-----------+
| 15sdfsd4 | Spiderman |
+-----------+-----------+
rating
+----+--------+----------+----------+
| id | rating | username | movie_id |
+----+--------+----------+----------+
| 1 | 4 | jack | 15sdfsd4 |
| 2 | 3 | mick | 15sdfsd4 |
+----+--------+----------+----------+
comment
+----+----------+--------------------+----------+
| id | username | body | movie_id |
+----+----------+--------------------+----------+
| 1 | charles | I loved this movie | 15sdfsd4 |
| 2 | mick | Nice sound fx | 15sdfsd4 |
+----+----------+--------------------+----------+
I would like to query for a list of movie ids and get a summary of the avg rating and the nr of comments.
I tried something like
ids = ['15sdfsd4','54fdf5d']
m = Movie.objects.filter(source_id__in=ids).annotate(Avg('rating'), Count('comment'))
I would expect a comment count of 2 and an avg rating of 3.5 for the movie with id 15sdfsd4. Instead I get a comment count of 4 and an avg rating of 1.5 which I can't make much sense of...
Do you have any suggestion? Thanks
Upvotes: 0
Views: 2379
Reputation: 15738
There are two thing that are wrong with following solution
Considering count aggregate has distinct and average with duplicates is same this would probably work
m = Movie.objects.filter(source_id__in=ids).annotate(
Avg('rating__rating'),
Count('comment',distinct=True)
)
Upvotes: 1