首页 > 解决方案 > Django 获取外键对象

问题描述

我来自 .NET Core,我很好奇 Django 是否有任何类似于 .NET Core 的预测。例如,我可以在 .NET Core 模型中描述一个关系,然后再查询它。所以,如果Articles可以有一个Author我可以做类似的事情:

var articles = dbContext.Where(article.ID == id).Inclue(a => a.author);

我会得到的是附有作者的文章。

Django中有类似的东西吗?如何在模型中描述的 Django 中加载相关数据?

标签: pythondjangopython-3.xdjango-models

解决方案


是的。您编写的查询或多或少相当于:

Article.objects.filter(id=some_id).prefetch_related('author')

或者:

Article.objects.filter(id=some_id).select_related('author')

select_related相对prefetch_related

如果Authors 的数量有限,或者更多是一对一的关系。如果您拉出大量Articles,并且几个Articles 映射到同一个 Authors ,通常最好使用prefetch_related:这将首先查找Author标识符,执行唯一性过滤器,然后将它们提取到内存中。

如果多个Authors 写一篇文章也是如此(因此是一对多多对多的关系)。因为这意味着如果我们JOIN在数据库级别执行 a ,我们会按照Author写该文章的 s 的数量重复每篇文章,并且按照他们编写Author的 s 的数量重复每篇Article文章。我们通常希望避免这种集合的这种“乘法”行为。所以在这种情况下prefetch_related将具有线性行为:首先获取相关Article的 s,然后获取相关Author的 s。

相关对象的延迟加载

但是您实际上不需要prefetch_related为单个实例执行 a。如果您加载一篇文章,您可以简单地使用some_article.author. 如果相应的Author实例还没有加载,Django 将执行一个额外的查询来获取相关的Author实例。

因此 Django 可以以一种惰性的方式加载与相关对象相对应的属性:Article如果您在内存中获取它,Author它只会加载Django 每次都会进行新的查询并加载相关的对象。但是,如果您想批量处理 s列表,建议您这样做,因为它们会导致获取所有相关对象的查询数量有限,而不是每个相关实例一个查询。Journal.editorJournalAuthorArticleselect_relatedprefect_related

如果一个人经常需要获取零个或最多几个相关实例(例如,因为它取决于Article我们是否真正感兴趣的某些属性),相关对象的延迟加载可能会更有效Author


推荐阅读