Django ORM “.” 与 “_” 访问外键的 id 时

Django ORM "." vs "_" when access the id of foreign key

提问人:Tiancheng Liu 提问时间:8/15/2018 更新时间:8/15/2018 访问量:3009

问:

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
django orm 外键

评论

0赞 Sayse 8/15/2018
相关(可能重复?) - 从外键中选择单个字段 如果签出生成的查询,你会看到它不必要地提取了整个创作模型author.id

答:

12赞 willeM_ Van Onsem 8/15/2018 #1

从语义上讲没有区别。但是 with 的版本会比 .author_idauthor.id

如果你定义了一个外键,那么你实际上同时定义了两个 Django 字段:一个是 ,它是对你所引用的模型的模型对象的引用,另一个是字段 ,它包含你所引用的对象的主键的值。只有后者存储在数据库中(因为前者通常不能存储在数据库中)。fieldnamefieldname_id

请注意,如果要访问 ,通常这意味着必须执行额外的查询,因为除非显式加载 ,否则这些关系不会立即加载,而是延迟加载:它需要额外的数据库来获取相关对象。当然,一个额外的查询并不重要,但是如果你在一个循环中这样做,那么这会导致 n+1 问题:你将需要 1 个查询来获取书籍,以及 n 个查询来获取每本书的作者。.author.select_related(..)Authorfor

请注意,如前所述,有一些方法可以减少对 和 相关对象的查询量。但它仍然会导致传输更多数据。如果您对 的主键感兴趣,则可以使用 ,它不需要额外的 fetch。prefetch_relatedselect_relatedAuthorauthor_id

评论

0赞 Tiancheng Liu 8/15/2018
字段“id”是唯一可以享受语法这个优势的字段吗?
1赞 willeM_ Van Onsem 8/15/2018
@TianchengLiu:主键(你可以有另一个主键,因为它存储在 s 的表中idBook
1赞 Tiancheng Liu 8/15/2018
谢谢,我知道。如果使用“.”,django 将查询作者表,如果使用“_”,它只是 book 表中的一个字段。