首页 > 解决方案 > 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

标签: djangoormforeign-keys

解决方案


语义没有区别。但是带有的版本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,这不需要额外的获取。


推荐阅读