使用 Django 按连接数查询多对多关系
Querying Many To Many relationship by number of joins using Django
我有两个模型:ActorModel和FilmModel加入如下:
FilmModel(models.Model):
actors = models.ManyToManyField(Actor, blank=True, related_name='film_actors')
ActorModel(models.Model):
name = models.CharField(max_length=40)
def __str__(self):
return self.imdb_id
我想为任何与 FilmModel 连接超过 5 个的实例过滤我的 ActorModel。我可以这样做:
actors = ActorModel.objects.all()
more_than_five_films = []
for actor in actors:
actor_film_list = FilmModel.objects.filter(actors__imdb_id=str(name))
if len(actor_film_list)>5:
more_than_five_films.append(actor)
但是,使用上面的代码会消耗大量的处理能力。有没有更有效的方法来找到超过 5 个连接的演员?例如,我可以在过滤阶段这样做吗?
您可以使用这样的查询:
more_than_five_films = ActorModel.objects.annotate(count=Count('film_actors')).filter(count__gt=5)
您通过 related_name
字段访问 ActorModel
的 FilmModel
个对象,通过计算与每个 ActorModel
对象,然后只过滤掉计数值大于5的对象。
Advice 对于您提供的代码永远不要在查询集上使用 len()
因为它会评估整个查询,这是昂贵且不需要的,因为您只需要一个计数价值。您应该使用 count()
函数,其中 returns 的数字与 len()
相同。它看起来像这样:
FilmModel.objects.filter(actors__imdb_id=str(name)).count()
我有两个模型:ActorModel和FilmModel加入如下:
FilmModel(models.Model):
actors = models.ManyToManyField(Actor, blank=True, related_name='film_actors')
ActorModel(models.Model):
name = models.CharField(max_length=40)
def __str__(self):
return self.imdb_id
我想为任何与 FilmModel 连接超过 5 个的实例过滤我的 ActorModel。我可以这样做:
actors = ActorModel.objects.all()
more_than_five_films = []
for actor in actors:
actor_film_list = FilmModel.objects.filter(actors__imdb_id=str(name))
if len(actor_film_list)>5:
more_than_five_films.append(actor)
但是,使用上面的代码会消耗大量的处理能力。有没有更有效的方法来找到超过 5 个连接的演员?例如,我可以在过滤阶段这样做吗?
您可以使用这样的查询:
more_than_five_films = ActorModel.objects.annotate(count=Count('film_actors')).filter(count__gt=5)
您通过 related_name
字段访问 ActorModel
的 FilmModel
个对象,通过计算与每个 ActorModel
对象,然后只过滤掉计数值大于5的对象。
Advice 对于您提供的代码永远不要在查询集上使用 len()
因为它会评估整个查询,这是昂贵且不需要的,因为您只需要一个计数价值。您应该使用 count()
函数,其中 returns 的数字与 len()
相同。它看起来像这样:
FilmModel.objects.filter(actors__imdb_id=str(name)).count()