提问人:Tiancheng Liu 提问时间:8/15/2018 更新时间:8/15/2018 访问量:3009
Django ORM “.” 与 “_” 访问外键的 id 时
Django ORM "." vs "_" when access the id of foreign key
问:
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
答:
12赞
willeM_ Van Onsem
8/15/2018
#1
从语义上讲,没有区别。但是 with 的版本会比 .author_id
author.id
如果你定义了一个外键,那么你实际上同时定义了两个 Django 字段:一个是 ,它是对你所引用的模型的模型对象的引用,另一个是字段 ,它包含你所引用的对象的主键的值。只有后者存储在数据库中(因为前者通常不能存储在数据库中)。fieldname
fieldname_id
请注意,如果要访问 ,通常这意味着必须执行额外的查询,因为除非显式加载 ,否则这些关系不会立即加载,而是延迟加载:它需要额外的数据库来获取相关对象。当然,一个额外的查询并不重要,但是如果你在一个循环中这样做,那么这会导致 n+1 问题:你将需要 1 个查询来获取书籍,以及 n 个查询来获取每本书的作者。.author
.select_related(..)
Author
for
请注意,如前所述,有一些方法可以减少对 和 相关对象的查询量。但它仍然会导致传输更多数据。如果您只对 的主键感兴趣,则可以使用 ,它不需要额外的 fetch。prefetch_related
select_related
Author
author_id
评论
0赞
Tiancheng Liu
8/15/2018
字段“id”是唯一可以享受语法这个优势的字段吗?
1赞
willeM_ Van Onsem
8/15/2018
@TianchengLiu:主键(你可以有另一个主键,因为它存储在 s 的表中。id
Book
1赞
Tiancheng Liu
8/15/2018
谢谢,我知道。如果使用“.”,django 将查询作者表,如果使用“_”,它只是 book 表中的一个字段。
评论
author.id