Tiancheng Liu
Tiancheng Liu

Reputation: 873

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)

Consider those two models. When I access this foreign key, what's the difference between those two ways:

id= Book.objects.get(pk=1).author.id
id= Book.objects.get(pk=1).author_id

Upvotes: 7

Views: 3414

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476574

Semantically there is no difference. But the version with author_id will be more efficient than author.id.

If you define a foreign key, then you actually defined two Django fields at once: the fieldname, which is a reference to a model object to the model to which you refer, and a field fieldname_id, that contains the value of the primary key to the object to which you refer. Only the latter is stored in the database (since the former can usually not be stored in a database).

Note that if you want to access the .author, usually this means that you have to perform an extra query, since those relations, unless explicitly loaded with .select_related(..), are not loaded immediately, but lazily: it requires an extra database to obtain the relevant Author object. Of course one extra query does not matter that much, but if you would for example do this in a for loop, then this results in the n+1-problem: you will need 1 query to fetch the books, and n queries to fetch the author of every book.

Note that there are - as mentioned before - ways to reduce the amount of querying for related objects with prefetch_related, and select_related. But still it will result in transferring more data. If you are only interested in the primary key of the Author, then you can use author_id, which does not require such extra fetch.

Upvotes: 13

Related Questions