Reputation: 11348
I am coming from .NET Core and I am curious if Django has anything similar to .NET Core's projections. For instance, I can describe a relationship in a .NET Core model and then later query for it. So, if Articles
can have an Author
I can do something like:
var articles = dbContext.Where(article.ID == id).Inclue(a => a.author);
What I would get back are articles that have their author attached.
Is there anything similar to this in Django? How can I load related data in Django that's described in the model?
Upvotes: 2
Views: 6220
Reputation: 476537
Yes. The query you wrote is more or less equivalent to:
Article.objects.filter(id=some_id).prefetch_related('author')
or:
Article.objects.filter(id=some_id).select_related('author')
select_related
versus prefetch_related
in case the number of Author
s is limited, or more a one-to-one relation. In case you pull a large number of Article
s, and several Article
s map to the same Author
, it is usually better to use prefetch_related
: this will first look for the Author
identifiers, perform a uniquness filter, and then fetch those into memory.
The same holds if multiple Author
s write one article (so a one-to-many or many-to-many relation). Since that would mean that if we perform a JOIN
at the database level, we repeat every article by the number of Author
s who wrote that article, and we repeat every Author
by the number of Article
s they wrote. We usually want to avoid this "multiplicative" behavior for such sets. So in that case prefetch_related
will have linear behavior: first fetching the relevant Article
s, next fetching the relevant Author
s.
But you actually do not need to perform a prefetch_related
for a single instance. In case you load an article, you can simply use some_article.author
. If the corresponding Author
instance is not yet loaded, Django will perform an additional query fetching the related Author
instance.
So Django can load attributes that correspond to related objects in a lazy manner: it simply loads the Article
if you fetch it in memory, and if you later need the Author
, or the Journal
, or the .editor
of the Journal
(which is for example an Author
as well), Django will each time make a new query and load related object(s). In case you want however to process a list of Article
s in batch, select_related
and prefect_related
are advisable, since they will result in a limited number of queries to fetch all related objects, instead of one query per related instance.
The lazy loading of related objects can be more efficient if one frequently has to fetch zero or at most a few related instances (for example because it depends on some attributes of the Article
whether we are really interested in the Author
after all).
Upvotes: 4
Reputation: 8314
Sounds like you are looking for select_related. This traverses FK relationships based on how they are created in your models.
Upvotes: 3