I have a Post
model which has ManyToMany relation with User
to reflect Likes feature. Moreover Post
has ForeignKey relation to itself since each post can be a comment to existing Post
(only one depth level is forced - there are no discussion trees).
Now I'm trying to use aggregates to get most active discussions. I want to calculate score for each Post
which is sum of its likes, comments, and likes of its comments.
Following SQL works perfectly:
SELECT "posting_post"."id",
"posting_post"."title",
"posting_post"."content",
"posting_post"."pub_date",
"posting_post"."parent_id",
"posting_post"."user_id",
COUNT(DISTINCT T4."id") AS "cc",
COUNT(DISTINCT "posting_post_likes"."id") AS "lc",
COUNT(DISTINCT T7."id") AS "clc"
FROM "posting_post"
LEFT OUTER JOIN "posting_post" T4 ON ("posting_post"."id" = T4."parent_id")
LEFT OUTER JOIN "posting_post_likes" ON ("posting_post"."id" = "posting_post_likes"."post_id")
LEFT OUTER JOIN "posting_post_likes" T7 ON (T4."id" = T7."post_id")
WHERE "posting_post"."parent_id" IS NULL
GROUP BY "posting_post"."id",
"posting_post"."title",
"posting_post"."content",
"posting_post"."pub_date",
"posting_post"."parent_id",
"posting_post"."user_id"
ORDER BY cc+lc+clc DESC LIMIT 10
When I try to use aggreagtions:
Post.objects.filter(parent=None).annotate(clc=models.Count('comments__likes', discinct=True), cc=models.Count('comments', distinct=True), lc=models.Count('likes', distinct=True))[:10]
Following SQL is generated:
SELECT "posting_post"."id",
"posting_post"."title",
"posting_post"."content",
"posting_post"."pub_date",
"posting_post"."parent_id",
"posting_post"."user_id",
COUNT(DISTINCT T4."id") AS "cc",
COUNT(DISTINCT "posting_post_likes"."user_id") AS "lc",
COUNT(T7."user_id") AS "clc"
FROM "posting_post"
LEFT OUTER JOIN "posting_post" T4 ON ("posting_post"."id" = T4."parent_id")
LEFT OUTER JOIN "posting_post_likes" ON ("posting_post"."id" = "posting_post_likes"."post_id")
LEFT OUTER JOIN "posting_post_likes" T7 ON (T4."id" = T7."post_id")
WHERE "posting_post"."parent_id" IS NULL
GROUP BY "posting_post"."id",
"posting_post"."title",
"posting_post"."content",
"posting_post"."pub_date",
"posting_post"."parent_id",
"posting_post"."user_id"
ORDER BY "posting_post"."pub_date" DESC LIMIT 10
Which is not working as I expect. Please note main difference:
COUNT(DISTINCT T7."id") AS "clc"
vs.
COUNT(T7."user_id") AS "clc"
Is there some way to force django to count id
instead of user_id
or some more clever way of using aggregates to achieve results like first SQL returns?