我想创建一个包含以下列的查询集
电影.id |电影.title |电影.description |电影.maximum_rating |电影.maximum_rating_user
以下是我的模型和我尝试过的代码。
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)
当我运行下面的代码时,控制台会打印以下内容: (基本上这显示了实验数据库中的所有数据)
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 | 标题 | 描述 | 评分 | 用户 |
---|---|---|---|---|
1 | 跳猫 | 狂奔 | 2 | 1 |
1 | 跳猫 | 狂奔 | 1 | 2 |
1 | 跳猫 | 狂奔 | 5 | 3 |
1 | 跳猫 | 狂奔 | 4 | 4 |
2 | 终结者 | 我会回来的! | 8 | 1 |
2 | 终结者 | 我会回来的! | 6 | 2 |
2 | 终结者 | 我会回来的! | 4 | 3 |
2 | 终结者 | 我会回来的! | 10 | 4 |
3 | 小飞象 | 华特迪士尼 | 6 | 1 |
3 | 小飞象 | 华特迪士尼 | 8 | 2 |
3 | 小飞象 | 华特迪士尼 | 9 | 3 |
3 | 小飞象 | 华特迪士尼 | 2 | 4 |
4 | 细红线 | 战时 | 9 | 1 |
4 | 细红线 | 战时 | 2 | 2 |
4 | 细红线 | 战时 | 5 | 3 |
4 | 细红线 | 战时 | 8 | 4 |
现在我想修改查询,以便它只返回评分具有最大值的每部电影的行。
当我删除第二个注释时,查询会为每部电影返回一行且评分最高,但用户没有被注释。
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 | 标题 | 描述 | 评分 |
---|---|---|---|
1 | 跳猫 | 狂奔 | 5 |
2 | 终结者 | 我会回来的! | 10 |
3 | 小飞象 | 华特迪士尼 | 9 |
4 | 细红线 | 战时 | 9 |
我应该如何修改查询以使其返回 abave 查询集但注释发布最高评分的用户?
答案 0 :(得分:1)
您可以使用 Subquery
expression [Django-odc] 来确定评价最高的用户:
from django.db.models import OuterRef, Subquery
def index(request, movie_id):
movies = Movie.objects.all().annotate(
maximum_rating=Max('ratings__score'),
max_user=Subquery(
Rating.objects.filter(
movie=OuterRef('pk')
).order_by('-score').values('user')[:1]
)
)
for movie in movies:
print(movie.id, movie.title, movie.description, movie.maximum_rating)
return HttpResponse("")