Skip to main content
 首页 » 编程设计

python之Django 获取外键对象

2025年05月04日29jpfss

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

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

我要取回的是附有作者的文章。

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

请您参考如下方法:

是的。您编写的查询或多或少等同于:

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

或:

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

select_related 与 prefetch_related

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

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

延迟加载相关对象

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

因此 Django 可以以惰性方式加载与相关对象相对应的属性:如果您在内存中获取 Article 并且稍后需要Author,或 Journal,或 Journal 的 .editor(例如 Author 以及),Django 每次都会进行新的查询并加载相关对象。但是,如果您想批量处理 Article 列表,建议使用 select_related 和 prefect_related,因为它们会导致数量有限获取所有相关对象的查询,而不是每个相关实例一个查询。

如果需要频繁地获取零个或最多几个相关实例,则相关对象的延迟加载会更有效(例如,因为它取决于 Article 的某些属性,我们是否真的毕竟对 Author 感兴趣)。