I want to create a queryset with following columns
movie.id | movie.title | movie.description | movie.maximum_rating | movie.maximum_rating_user
Below are my models and the code I have tried.
models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
pass
class Rating(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name="ratings")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="ratings")
score = models.DecimalField(decimal_places=2, max_digits=9)
class Movie(models.Model):
title = models.CharField(max_length=64)
description = models.TextField(max_length=4096)
When i run below code the following is printed in console: (basically this shows all data in the experimental database)
views.py
def index(request, movie_id):
movies = Movie.objects.all().annotate(
maximum_rating=Max('ratings__score'),
maximum_rating_user=F('ratings__user')
)
for movie in movies:
print(movie.id, movie.title, movie.description, movie.maximum_rating, movie.maximum_rating_user)
return HttpResponse("")
| id | title | description | rating | user |
|---|---|---|---|---|
| 1 | Jumping Cats | Running wild | 2 | 1 |
| 1 | Jumping Cats | Running wild | 1 | 2 |
| 1 | Jumping Cats | Running wild | 5 | 3 |
| 1 | Jumping Cats | Running wild | 4 | 4 |
| 2 | Terminator | I'll be back! | 8 | 1 |
| 2 | Terminator | I'll be back! | 6 | 2 |
| 2 | Terminator | I'll be back! | 4 | 3 |
| 2 | Terminator | I'll be back! | 10 | 4 |
| 3 | Dumbo | Walt Disney | 6 | 1 |
| 3 | Dumbo | Walt Disney | 8 | 2 |
| 3 | Dumbo | Walt Disney | 9 | 3 |
| 3 | Dumbo | Walt Disney | 2 | 4 |
| 4 | Thin Red Line | Wartimes | 9 | 1 |
| 4 | Thin Red Line | Wartimes | 2 | 2 |
| 4 | Thin Red Line | Wartimes | 5 | 3 |
| 4 | Thin Red Line | Wartimes | 8 | 4 |
Now i would like to modify the query so it only returns the row for each movie where the rating has the maximum value.
When i remove the second annotate the query returns a single row for each movie with the maximum rating but then the user is not annotated.
views.py
def index(request, movie_id):
movies = Movie.objects.all().annotate(
maximum_rating=Max('ratings__score'))
for movie in movies:
print(movie.id, movie.title, movie.description, movie.maximum_rating)
return HttpResponse("")
| id | title | description | rating |
|---|---|---|---|
| 1 | Jumping Cats | Running wild | 5 |
| 2 | Terminator | I'll be back! | 10 |
| 3 | Dumbo | Walt Disney | 9 |
| 4 | Thin Red Line | Wartimes | 9 |
How should i modify the query so it returns the abave queryset but annotes the user who posted the highest rating?