Django ORM:根据相关模型计数创建排名

Django ORM:根据相关模型计数创建排名,django,django-models,django-2.0,Django,Django Models,Django 2.0,我的数据库中有两个模型:Movie和Comment(它有一个外键指向Movie) 我想做的是创建一个电影排名,排名由相关评论的数量决定 我可以注释注释注释的数量并正确排序结果: from django.db.models import Count qs = Movie.objects.annotate(total_comments=Count('comment')).order_by('-total_comments') 这使我能够按照正确的顺序进行查询集,但我还想做一件事——为每一行注释“

我的数据库中有两个模型:
Movie
Comment
(它有一个外键指向
Movie

我想做的是创建一个
电影
排名,排名由相关
评论的数量决定

我可以注释注释注释的数量并正确排序结果:

from django.db.models import Count

qs = Movie.objects.annotate(total_comments=Count('comment')).order_by('-total_comments')
这使我能够按照正确的顺序进行查询集,但我还想做一件事——为每一行注释“rank”

所以我的问题是:我如何为结果的每一行添加“rank”注释?请注意,具有相同评论量的电影必须具有相同的排名

|  movie_title | total_comments | rank |
|--------------|----------------|------|
| mov1         | 10             | 1    |
| mov2         | 5              | 2    |
| mov3         | 5              | 2    |
| mov4         | 3              | 3    |
我试图使用,因为有些例子对我来说似乎是合法的:

from django.db.models import F, Window

dense_rank = Window(
    expression=DenseRank(),
    order_by=F('total_comments').desc()
)

qs = Movie.objects.annotate(total_comments=Count('comment')).annotate(rank=dense_rank)

但运行此查询将引发
django.db.utils.OperationalError:near”(“:语法错误

行数
,如果查询的顺序正确:

from django.db.models import Count
from django.db.models.expressions import F, Window
from django.db.models.functions.window import RowNumber

qs = (Movie.objects
    .annotate(total_comments=Count('comment'))
    .order_by('total_comments')
    .annotate(rank = Window(expression=RowNumber())
)
但是,由于行号是记录序列中固有的,Kevin正确地提出了一种简单的Python方法(例如,
enumerate
),因为您将在某个时刻迭代记录集

如果您希望记录集的顺序不同于排名,那么使用带有单独的
order\u by
参数的
Window
是有意义的


我不确定所有后端是否支持
RowNumber

请注意,您也可以在Python中计算排名,因为这只是为了显示。如果无法通过数据库查询获得预期结果,我会这样做。您是否提出了可行的解决方案?此问题中出现的问题是由使用SQLite db后端。在我切换到Postgres后,代码开始按预期工作。在提出问题之前,我使用的是SQLite后端。现在,我也在Postgres上测试了它,来自我原始问题的查询也按预期工作!这很奇怪,因为它似乎是SQLite。我的查询似乎也只在PG上工作,而不是SQLite,甚至你它在SQLite shell中执行得很好。窗口函数非常新,可能还没有100%正常工作。
from django.db.models import Count
from django.db.models.expressions import F, Window
from django.db.models.functions.window import RowNumber

qs = (Movie.objects
    .annotate(total_comments=Count('comment'))
    .order_by('total_comments')
    .annotate(rank = Window(expression=RowNumber())
)