Менеджер «многие ко многим» не может соответствовать нескольким отношениям одновременно.На уровне базы данных все сводится к выбору и группировке.
Таким образом, естественно, единственный вопрос, на который база данных может ответить, это: перечислите действия, в которых участвуют эти люди, сгруппируйте их по фильмам и покажите толькоэти фильмы имеют то же количество действующих лиц, что и персонажи.
В переводе на ORM говорят, что это выглядит так:
actors = Person.objects.filter(name__in=('Keanu Reaves', 'Laurence Fishburne'))
qs = Movie.objects.filter(activity__name='actor',
activity__person__in=actors)
qs = qs.annotate(common_actors=Count('activity'))
all_actors_in_common = qs.filter(common_actors=actors.count())
Этот запрос на самом деле неплохой:
SELECT "cmdb_movie"."id", "cmdb_movie"."title", COUNT("cmdb_activity"."id") AS "common_actors"
FROM "cmdb_movie"
LEFT OUTER JOIN "cmdb_activity" ON ("cmdb_movie"."id" = "cmdb_activity"."movie_id")
WHERE ("cmdb_activity"."person_id" IN (SELECT U0."id" FROM "cmdb_person" U0 WHERE U0."name" IN ('Keanu Reaves', 'Laurence Fishburne'))
AND "cmdb_activity"."name" = 'actor' )
GROUP BY "cmdb_movie"."id", "cmdb_movie"."title", "cmdb_movie"."id", "cmdb_movie"."title"
HAVING COUNT("cmdb_activity"."id") = 2
У меня также есть небольшое приложение, которое я использовал для проверки этого, но я не знаю, кому это нужно, и где его разместить.