Я создаю сайт 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, если это имеет значение.
Приветствуются любые идеи!