如何避免Django中的n + 1选择? [英] How to avoid n+1 select in django?

查看:90
本文介绍了如何避免Django中的n + 1选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a very simple datamodel with a one to many relationship between video and comments

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

class Comment(models.Model):
    title = models.CharField(max_length=128)
    video = models.ForeignKey('Video')
        .....

我想查询视频并获取整个对象图(带有所有注释的视频)。查看sql,我看到它做了两个选择,一个选择视频,一个选择注释。如何避免这种情况?我想加入并立即抓住所有东西。

I want to query for videos and grab the whole object graph (videos with all the comments). Looking at the sql, I see it does two selects, one for the Videos and one for the Comments. How do I avoid that? I want to do a join and grab everything at once.

是否可以使用django做到这一点?

Is it possible to do this with django?

推荐答案

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

For ForeignKey, you can use selected_related():

Comment.objects.select_related('video').all()

它将仅生成一个查询,收集

It will generate one query only, gathering coments for you as well as videos.

对于更复杂的内容(例如M2M),您需要外部应用程序,例如取消联接进行优化,但它使用SQL查询将其放回对象中。

For something more complex (such as M2M), you need an external app such as unjoinify to make optimizations but it uses SQL queries to then put them back in objects.

如果您对此不满意(我是),则有其他选择:

If you are unconfortable with this (I am), you have some alternatives:

  • django-queryset-transform: not a full solution, but helps
  • django-batch-select: roughtly a select_related that works with M2M and reverse relations.

这篇关于如何避免Django中的n + 1选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆