Я хочу агрегировать подсчет работы при использовании одного и того же видеоресурса и подсчет пользователей на основе количества отдельных пользователей. Я попробовал два метода для этого, но получил противоречивые результаты.
Проблема в том, что два результата qset в моем коде разные. qset1 правильный, но qset2 неправильный, потому что он не исключает тех же пользователей.
Мой вопрос: что мне делать, если я не хочу использовать Raw SQL, как qset1, и хочу получить правильный результат ?
Мой код выглядит следующим образом:
#models concerned
class Video(models.Model):
name = models.CharField(max_length=100, verbose_name=_('video name'))
class Work(models.Model):
video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='works_of_video', verbose_name=_('video'))
maker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='works_of_maker', verbose_name=_('maker'))
#rawsql for get_queryset()
video_sql = u'''SELECT COUNT(*) AS "num"
From (SELECT DISTINCT maker_id
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = ("video_manage_video"."id") AND U2."gender" IN (%s))
)'''
#views concerned
def get_queryset(request):
what_gender = (0, 1)
vall = Video.object.all()
works = Work.objects.filter(video=OuterRef('pk')).filter(maker__gender__in=what_gender)
works_makers = works.values('maker','video').distinct()
# the next annotate use RawSQL of video_sql
qset1 = vall.annotate(works_num=Subquery(works.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))\
.annotate(makers_num=RawSQL(video_sql, (gender_str,)))
# the next annotate use Subquery that try to distinct queryset that excluded the same users
qset2 = vall.annotate(works_num=Subquery(works.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))\
.annotate(makers_num=Subquery(works_makers.values('video').annotate(num=Count('*')).values('num'), output_field=IntegerField()))
return render(request, 'video_manage/video_data.html')
'''
######sql sentenc of qset2 created by django:
SELECT "video_manage_video"."id",
"video_manage_video"."name",
(SELECT COUNT(*) AS "num"
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = "video_manage_video"."id"
AND U2."gender" IN (0,
1))
GROUP BY U0."video_id") AS "works_num",
(SELECT COUNT(*) AS "num"
From (SELECT DISTINCT maker_id
FROM "video_manage_work" U0
INNER JOIN "video_manage_demouser" U2 ON (U0."maker_id" = U2."id")
WHERE (U0."video_id" = ("video_manage_video"."id")
AND U2."gender" IN (0,
1))
)
) AS "makers_num"
FROM "video_manage_video";
'''