将 Django ORM 用于计算字段

Using Django ORM for computed field

我有一个网络应用程序记分牌。每个用户post值10分,每条用户评论值1分。我想先按最高分排序。所以对于原始 SQL,它将是:

select username, email,
    ( select 10 * count(*) from posts_post where accounts_customuser.id = posts_post.author_id ) +
    ( select count(*) from posts_comment where accounts_customuser.id = posts_comment.author_id ) total 
    from accounts_customuser
    order by total desc, username;

当然,Django 的想法是利用 ORM 并避免原始 SQL。我看到有聚合,所以它接近于这样的东西:

queryset = get_user_model().objects.annotate(post_count=Count('posts'),
           comment_count=Count('comment')).order_by('-post_count', '-comment_count', 'username')

但是,这不太正确,因为如果我有一个用户有 1 个 post 和 1 个评论(11 分),然后有一个用户有 0 个 post 和 12 个评论(12 分),使用上述 QuerySet,它们不会被 ORM 正确排序。我尝试利用 F:

# Note:  CustomUser is what get_user_model() returns
CustomUser.objects.annotate(post_count=Count('posts'), comment_count=Count('comment'),
        total=Sum(F('post_count') * 10 + F('comment_count'))
    ).order_by('-post_count', '-comment_count', 'username')

但是,这会引发以下错误:

FieldError: Cannot compute Sum('<CombinedExpression: F(post_count) * Value(10) +
    F(comment_count)>'): '<CombinedExpression: F(post_count) * Value(10) + 
    F(comment_count)>' is an aggregate

我不确定从这里到哪里去。有人能给我指出正确的方向吗?

得到了the answer from KenWhitesell on the Django forums

显然使用 Sum 是一个错误,因为我的聚合是奇异值,所以解决方案是:

CustomUser.objects.annotate(
    post_count=Count('posts'), 
    comment_count=Count('comment'),
    total=F('post_count') * 10 + F('comment_count')
).order_by('-post_count', '-comment_count', 'username')