11

単純なメッセージングシステムでのユーザーアクティビティの概要をテンプレートに入力する必要があります。メッセージの送信者ごとに、送信されるメッセージの数と個別の受信者の数が必要です。

モデルの簡略化されたバージョンは次のとおりです。

class Message(models.Model):
    sender = models.ForeignKey(User, related_name='messages_from')
    recipient = models.ForeignKey(User, related_name='messages_to')
    timestamp = models.DateTimeField(auto_now_add=True)

SQLでこれを行う方法は次のとおりです。

SELECT sender_id, COUNT(id), COUNT(DISTINCT recipient_id)
    FROM myapp_messages
    GROUP BY sender_id;

ORMクエリでの集計に関するドキュメントを読んでいますが、annotate()は最初のCOUNT列を処理できますが、COUNT(DISTINCT)の結果を取得する方法がわかりません(extra(select = {})でも動作していないようですが、動作していません)。これをDjangoORMクエリに変換できますか、それとも生のSQLをそのまま使用する必要がありますか?

4

2 に答える 2

9

この回答に見られるように、実際に個別に使用して一緒に数えることができます:https ://stackoverflow.com/a/13145407/237091

あなたの場合:

SELECT sender_id, COUNT(id), COUNT(DISTINCT recipient_id)
FROM myapp_messages
GROUP BY sender_id;

次のようになります:

Message.objects.values('sender').annotate(
    message_count=Count('sender'),
    recipient_count=Count('recipient', distinct=True))
于 2014-04-07T17:55:33.277 に答える
4
from django.db.models import Count

messages = Message.objects.values('sender').annotate(message_count=Count('sender'))

for m in messages:
    m['recipient_count'] = len(Message.objects.filter(sender=m['sender']).\
                              values_list('recipient', flat=True).distinct())
于 2013-02-12T19:25:44.380 に答える