繁体   English   中英

如何使用 django 模型向已注释的查询集添加第二个注释

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM