Django ORM : create ranking based on related model count

标签 django django-models django-2.0

我的数据库中有 2 个模型:MovieComment(它有一个指向 Movie 的外键)。

from django.db import models


class Movie(models.Model):
    title = models.CharField(max_length=120, blank=False, unique=True)

class Comment(models.Model):
    movie = models.ForeignKey(
        movie_models.Movie, null=False, on_delete=models.CASCADE
    )
    body = models.TextField(blank=True)

我想做的是创建一个 Movies 排名,其中排名由相关 Comments 的数量决定。

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

from django.db.models import Count

qs = Movie.objects.annotate(
    total_comments=Count('comment')
).order_by('-total_comments')

这为我提供了正确顺序的查询集,但我还想做一件事 - 为每一行注释“排名”。

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

|  movie_title | total_comments | rank |
|--------------|----------------|------|
| mov1         | 10             | 1    |
| mov2         | 5              | 2    |
| mov3         | 5              | 2    |
| mov4         | 3              | 3    |

我尝试使用 window functions ,因为有些例子对我来说似乎是合法的:

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 "(": syntax error

最佳答案

如果查询顺序适当,

RowNumber 应该足够了:

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),因为您将在某些时候迭代记录集无论如何点。

如果您希望记录集的排序与排名的排序不同,那么将 Window 与单独的 order_by 参数一起使用是有意义的。

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

关于 Django ORM : create ranking based on related model count,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55260238/

相关文章:

django - 避免在不使用 raise Exception 的情况下将实例保存在 pre_save 信号中

python - Django `auth` 和 `contenttypes` 中断 syncdb

python - Django 在模型字段更新后将值转换为元组

python-3.x - django.core.exceptions.ImproperlyConfigured : WSGI application 'wsgi.application' could not be loaded; Error importing module

Django ContentTypes 将 uuid 字段转换为整数字段

python - “函数”对象没有属性 'as_view'

django - 我可以以某种方式在 Django ManyToMany 字段中使用 to_field 参数吗?

python - Django 创建与现有外键数据库条目相对应的新条目

python - Django : How can I implement a remember me key on my login page

django - 在 django_tex 中编译两次