在Django Doc中,

select_related()"遵循"外键关系,在执行查询时 Select 其他相关对象数据.

prefetch_related()对每个关系进行单独的查找,并在Python中进行"连接".

"加入python"是什么意思?有人能举例说明吗?

我的理解是,对于外键关系,使用select_related;对于M2M关系,使用prefetch_related.对吗?

推荐答案

你的理解基本上是正确的.当要 Select 的对象是单个对象时,使用select_related,即OneToOneFieldForeignKey.当你要得到一组东西时,你用prefetch_related,所以你说的是ManyToManyField,或者反过来说是ForeignKey.为了澄清我所说的"ForeignKeys反转"是什么意思,这里有一个例子:

class ModelA(models.Model):
    pass

class ModelB(models.Model):
    a = ForeignKey(ModelA)

ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship

不同之处在于,select_related执行SQL联接,因此从SQL server将结果作为表的一部分返回.另一方面,prefetch_related执行另一个查询,因此减少了原始对象中的冗余列(上例中为ModelA).你可以用prefetch_related来表示任何你可以用select_related来表示的事情.

折衷是prefetch_related必须创建一个ID列表并将其发送回服务器,这可能需要一段时间.我不确定是否有一个很好的方式在交易中做到这一点,但我的理解是,Django总是只发送一个列表,并说 Select ...其中pk在(…,…,…)大体上在这种情况下,如果预取的数据是稀疏的(比如与人们的地址链接的美国州对象),这可能是非常好的,但是如果更接近一对一,这可能会浪费大量通信.如果有疑问,try 两种方法,看看哪一种效果更好.

上面讨论的所有内容基本上都是关于与数据库的通信.然而,在Python端,prefetch_related有一个额外的好处,即使用单个对象来表示数据库中的每个对象.将在Python中 for each "父"对象创建select_related个重复对象.由于Python中的对象具有相当大的内存开销,因此这也可以作为一个考虑因素.

Python相关问答推荐

计算每月过go x年的平均值

每个组每第n行就有Pandas

如何将不同长度的新列添加到现有的框架中

如何编写一个正规表达式来查找序列中具有2个或更多相同辅音的所有单词

Plotly:如何更改Heatmap中彩色条的勾选文本

inspect_asm不给出输出

将numpy矩阵映射到字符串矩阵

如何从FDaGrid实例中删除某些函数?

如何使用pytest来查看Python中是否存在class attribution属性?

pyscript中的压痕问题

组/群集按字符串中的子字符串或子字符串中的字符串轮询数据框

driver. find_element无法通过class_name找到元素'""

Pandas Loc Select 到NaN和值列表

如何在Python中找到线性依赖mod 2

Pandas Data Wrangling/Dataframe Assignment

基于行条件计算(pandas)

为什么常规操作不以其就地对应操作为基础?

PYTHON、VLC、RTSP.屏幕截图不起作用

查看pandas字符列是否在字符串列中

在Python中控制列表中的数据步长