如何让Django manytomany经理同时匹配几个关系?

e-s*_*tis 8 django orm many-to-many

我有这个型号:

class Movie(models.Model):
    # I use taggit for tag management
    tags = taggit.managers.TaggableManager()

class Person(models.Model):
    # manytomany with a intermediary model
    movies = models.ManyToManyField(Movie, through='Activity')

class Activity(models.Model):
    movie = models.ForeignKey(Movie)
    person = models.ForeignKey(Person)
    name = models.CharField(max_length=30, default='actor')
Run Code Online (Sandbox Code Playgroud)

而且我想要匹配一部与另一部演员相同的电影.Not one actor in common, but all the actors in common.

所以我不想要这个:

# actors is a shortcut property
one_actor_in_common = Movie.object.filter(activities__name='actor', 
                                           team_members__in=self.movie.actors)
Run Code Online (Sandbox Code Playgroud)

我想要的东西会让"Matrix I"与"Matrix II"相匹配,因为他们分享'Keanu Reeves'和'Laurence Fishburne',但不匹配"Speed"因为他们分享'Keanu Reeves'而不是'Laurence Fishburne'.

tba*_*ack 7

多对多的经理不能同时匹配几个关系.在数据库级别下来,这一切都归结为选择和分组.

因此,自然而然地说,数据库能够回答的唯一问题是:列出涉及这些人的行为活动,通过电影对它们进行分组,并仅显示那些具有与人类相同数量的表演活动的电影.

转换为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())
Run Code Online (Sandbox Code Playgroud)

这产生的查询实际上并不坏:

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
Run Code Online (Sandbox Code Playgroud)

我还有一个小应用程序,我曾经测试过这个,但我不知道有人需要它,也不知道在哪里托管它.