我正在建立一个 Django 站点进行讨论。用户可以参与讨论,也可以对讨论和讨论中的消息投赞成票。一个简化的数据模型如下:
class Discussion:
name = models.CharField(max_length=255)
class Message:
owner = models.ForeignKey(User, related_name='messages')
body = models.TextField()
discussion = models.ForeignKey(Discussion, related_name='messages')
class MessageApprovalVote:
owner = models.ForeignKey(User, related_name='message_approval_votes')
message = models.ForeignKey(Message, related_name='approval_votes')
class DiscussionApprovalVote:
owner = models.ForeignKey(User, related_name='discussion_approval_votes')
discussion = models.ForeignKey(Discussion, related_name='approval_votes')
我想选择前 20 个“最活跃”的讨论,这意味着按该讨论的消息数、消息批准投票总数和讨论批准投票数的总和排序,或者(在伪代码中):
# Doesn't work
Discussion.objects.
order_by(Count('messages') +
Count('approval_votes') +
Count('messages__approval_votes'))
使用注释,我可以计算三个评分因素的总和:
scores = Discussion.objects.annotate(
total_messages=Count('messages', distinct=True),
total_discussion_approval_votes=Count('approval_votes', distinct=True),
total_message_approval_votes=Count('messages__approval_votes', distinct=True))
然后,当我找到extra
方法时,我以为我正在做某事:
total_scores = scores.extra(
select={
'score_total': 'total_messages + total_discussion_approval_votes + total_message_approval_votes'
}
)
然后就可以做到:
final_answer = total_scores.order_by('-score_total')[:20]
但extra
电话给出了一个DatabaseError
:
DatabaseError: column "total_messages" does not exist
LINE 1: SELECT (total_votes + total_messages + total_persuasions) AS...
因此我被挫败了。该extra
方法不能引用annotate
d 字段吗?除了使用原始 sql 查询之外,还有其他方法可以做我想做的事情吗?如果这有所作为,我正在使用 Postgres。
任何见解将不胜感激!