如何在django中避免n + 1选择?

bvk*_*bvk 10 django orm join

我有一个非常简单的数据模型,视频和评论之间有一对多的关系

class Video(models.Model):
    url = models.URLField(unique=True)
    .....

class Comment(models.Model):
    title = models.CharField(max_length=128)
    video = models.ForeignKey('Video')
        .....
Run Code Online (Sandbox Code Playgroud)

我想查询视频并抓取整个对象图(包含所有评论的视频).看看sql,我看到它有两个选择,一个用于视频,一个用于注释.我该如何避免?我想做一个加入并立刻抓住所有东西.

用django可以做到这一点吗?

e-s*_*tis 13

对于ForeignKey,您可以使用selected_related():

Comment.objects.select_related('video').all()
Run Code Online (Sandbox Code Playgroud)

它只会生成一个查询,为您收集内容以及视频.

对于更复杂的东西(例如M2M),您需要一个外部应用程序(如unjoinify)进行优化,但它使用SQL查询然后将它们放回到对象中.

如果你对此不感兴趣(我是),你有一些选择:


fij*_*ter 1

看看select related是否按照您期望的方式工作,它就是为此而设计的。