ディスカッション用の 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'))
注釈を使用して、3 つのスコア要因それぞれの合計を計算できます。
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...
したがって、私は失敗しました。メソッドはd フィールドextra
を参照できませんか? annotate
生のSQLクエリを使用する以外に、私がやろうとしていることを行う別の方法はありますか? それが違いを生む場合、私はPostgresを使用しています。
どんな洞察も大歓迎です!