使用 Django 按连接数查询多对多关系
Posted
技术标签:
【中文标题】使用 Django 按连接数查询多对多关系【英文标题】:Querying Many To Many relationship by number of joins using Django 【发布时间】:2021-01-07 23:33:39 【问题描述】:我有两个模型: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 个连接的演员?例如,我可以在过滤阶段这样做吗?
【问题讨论】:
docs.djangoproject.com/en/3.1/topics/db/aggregation 感谢仍在努力实施-您能建议吗? 【参考方案1】:你可以像这样使用查询:
more_than_five_films = ActorModel.objects.annotate(count=Count('film_actors')).filter(count__gt=5)
您通过related_name
字段访问ActorModel
的FilmModel
对象,通过计算与每个ActorModel
对象相关的FilmModel
对象的数量来注释名为count
的新字段,然后仅过滤掉具有计数的对象值大于 5。
建议是永远不要在查询集上使用len()
,因为它会评估整个查询,这很昂贵且不需要,因为您只需要一个计数值。您应该使用count()
函数,它返回的数字与len()
一样。它看起来像这样:
FilmModel.objects.filter(actors__imdb_id=str(name)).count()
【讨论】:
谢谢!非常有帮助! 乐于助人!如果您发现答案有帮助,请将其标记为已接受答案(绿色勾号)和/或给它投票。以上是关于使用 Django 按连接数查询多对多关系的主要内容,如果未能解决你的问题,请参考以下文章