Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 712
Tiancheng Liu Avatar asked Jan 02 '23 23:01

Tiancheng Liu


1 Answers

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.

like image 164
Willem Van Onsem Avatar answered Jan 05 '23 14:01

Willem Van Onsem