django - Django ORM“。” vs "_" 访问外键 id 时
问题描述
class Author(models.Model):
name = models.CharField(max_length=120)
class Book(models.Model):
name = models.CharField(max_length=20)
author= models.ForeignKey(Author)
考虑这两个模型。当我访问这个外键时,这两种方式有什么区别:
id= Book.objects.get(pk=1).author.id
id= Book.objects.get(pk=1).author_id
解决方案
语义上没有区别。但是带有的版本author_id
会比.author.id
如果你定义了一个外键,那么你实际上一次定义了两个 Django 字段:fieldname
,它是对模型对象的引用,它指向你所引用的模型,以及一个 field fieldname_id
,它包含对象的主键的值你所指的。只有后者存储在数据库中(因为前者通常不能存储在数据库中)。
请注意,如果您想访问.author
,通常这意味着您必须执行额外的查询,因为除非显式加载这些关系,否则.select_related(..)
不会立即加载,而是延迟加载:它需要额外的数据库来获取相关Author
对象。当然,一个额外的查询并不重要,但是如果您例如在一个for
循环中执行此操作,那么这会导致n+1问题:您将需要 1 个查询来获取书籍,并且需要n 个查询来获取每本书的作者。
请注意,如前所述,有一些方法可以减少使用 和 查询相关对象的prefetch_related
数量select_related
。但它仍然会导致传输更多数据。如果您只对 的主键感兴趣,Author
那么您可以使用author_id
,这不需要额外的获取。
推荐阅读
- python - 每当我使用拟合模型摘要时计算机冻结
- python - 更改中间激活/输出并观察 TF2/Keras 中的预测
- php - 如何将自动增量 ID 重置为以前的 ID
- java - java:如果我为变量分配了与之前相同的值,它会改变内存还是 JIT 能识别这一点?
- javascript - 在控制台中模拟调用 onMouseDown
- python - 获取数字列表的更快方法
- wordpress - 我可以在哪里编辑似乎不在代码中的 wordpress 文本?
- ruby-on-rails - 我无法在我的 Rails 应用程序中创建 manifest.json
- wordpress - Wordpress 回显或获取除最后 6 个字符外的单个帖子标题
- mongodb - 如何在 F# 中对 Mongo 集合进行排序