Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django select_related for multiple foreign keys

How does select_related work with a model which has multiple foreign keys? Does it just choose the first one?

class Model: fkey1, fkey2, fkey3...

The documentation doesn't say anything about this, at least not in where the method is specified.

NOTE: Maybe I'm the only one who will get confused. I guess select_related is just a performance booster (I can see that) but I had the wrong idea that it was something else.

like image 519
dtc Avatar asked Jan 17 '13 18:01

dtc


People also ask

Can I have multiple foreign keys in a table Django?

If you have more than one foreign key, a validation error will be raised. Your intermediate model must contain one - and only one - foreign key to the source model (this would be Group in our example). If you have more than one foreign key, a validation error will be raised.

Can a model have two foreign keys in Django?

First of all, anything is possible. Models can have multiple foreign keys.

What's the difference between Select_related and Prefetch_related in Django ORM?

select_related() “follows” foreign-key relationships, selecting additional related-object data when it executes its query. prefetch_related() does a separate lookup for each relationship and does the “joining” in Python.

What does Select_related do in Django?

Django offers a QuerySet method called select_related() that allows you to retrieve related objects for one-to-many relationships. This translates to a single, more complex QuerySet, but you avoid additional queries when accessing the related objects. The select_related method is for ForeignKey and OneToOne fields.


3 Answers

If your model has multiple foreign keys you can:

  • Call .select_related(), that will “follow” all non-null foreign-key relationships
  • Call .select_related('foreign_key1', 'foreign_key2', ...), that will “follow” only the foreign-key provided as arguments.

Note that "to follow a FK relationship" means selecting additional related-object data when the query is executed (by performing a SQL join). This will make the main query heavier but can be used to avoid N + 1 queries problem.

According to select_related documentation, the first method (without arguments) is not recommended as "it is likely to make the underlying query more complex, and return more data, than is actually needed."


If your model has "nested" foreign keys with other models (i.e. Book <>-- Author <>-- Hometown) you can also use select_related as follow:

  • Call Book.select_related('author__hometown'), that will “follow” the author's foreign-key (in Book model) and the hometown's foreign-key (in Author model).

If your model has many-to-many or many-to-one relations you would like to retrieve from the database, you should take a look at prefetch_related.

like image 135
Martín De la Fuente Avatar answered Oct 05 '22 12:10

Martín De la Fuente


You can use select_related in a chain as following

Comment.objects.select_related('user').select_related('article').all()
like image 41
Chemical Programmer Avatar answered Oct 05 '22 11:10

Chemical Programmer


On the contrary, the documentation is very clear on the matter. It says that by default all ForeignKeys are followed, but you can give the method a list of fields and it will only follow those relationships.

like image 45
Daniel Roseman Avatar answered Oct 05 '22 11:10

Daniel Roseman