[英]How to add a second annotation to an already annotated queryset with django models
我想用以下列创建一个查询集
电影.id | 电影.title | 电影说明 | 电影.maximum_rating | movie.maximum_rating_user
以下是我的模型和我尝试过的代码。
模型.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)
当我运行下面的代码时,控制台中会打印以下内容:(基本上这显示了实验数据库中的所有数据)
视图.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 |
现在我想修改查询,以便它只返回评级具有最大值的每部电影的行。
当我删除第二个注释时,查询会为每个具有最高评分的电影返回一行,但随后不会对用户进行注释。
视图.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查询集但注释发布最高评分的用户?
您可以使用Subquery
表达式 [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("")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.