Count
エラーメッセージが示すように、そのように使用することはできません:
SyntaxError: キーワードを式にすることはできません
の引数はCount
、 のような単純な文字列でなければなりませんuser_activity__rating
。
Avg
良い代替手段は、 と を一緒に使用することだと思いますCount
:
activities = Base_Activity.objects.all().annotate(
a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).order_by(
'-a', '-c'
)
アクティビティが最も多いアイテムはrating=1
平均が最も高く、平均が同じユーザーの中で最もアクティビティが多いアイテムが上位に表示されます。
反対票のある項目を除外する場合は、 の後に適切なfilter
またはexclude
操作を追加してくださいannotate
。次に例を示します。
activities = Base_Activity.objects.all().annotate(
a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).filter(user_activity__rating__gt=0).order_by(
'-a', '-c'
)
アップデート
反対票を無視して、賛成票順に並べられたすべてのアイテムを取得するには、次のように生のクエリを使用するしかないと思います。
from django.db import connection
sql = '''
SELECT o.id, SUM(v.rating > 0) s
FROM user_activity o
JOIN rating v ON o.id = v.user_activity_id
GROUP BY o.id ORDER BY s DESC
'''
cursor = connection.cursor()
result = cursor.execute(sql_select)
rows = result.fetchall()
注: モデルのテーブル名をハードコーディングする代わりに、モデルからテーブル名を取得します。たとえば、モデルが と呼ばれている場合、Rating
そのテーブル名を で取得できますRating._meta.db_table
。
このクエリを sqlite3 データベースでテストしましたが、SUM
そこにある式がすべての DBMS で機能するかどうかはわかりません。ところで、テストするのに最適な Django サイトがありました。ここでは、賛成票と反対票も使用しています。賛成票と反対票をカウントするために非常によく似たモデルを使用しますが、それらをsum
値、stackoverflow スタイルで並べ替えます。興味があれば、このサイトはオープンソースです。