Interested in knowing how lazy loading is achieved in frameworks like Django. When is the decision made to perform the join? And is there a way to force eager loading in Django? Are there times when you would need to force Django to eager load?
The general answer is that Django makes the decision to perform the query when you actually ask for some records. Most commonly this means iterating over the queryset (for record in queryset:
) or using the list()
built-in function to convert the queryset to a list.
See When QuerySets are evaluated for more specifics from the official docs.
It accomplishes this by defining a class, called QuerySet
in django/db/models/query.py
, where the special methods like __repr__
, __getitem__
and __iter__
are coded to do the right thing.
If you need to force eager loading just run the built-in Python list function on the queryset, like:
qs = SomeModel.objects.all()
ql = list(qs)
This call to list()
will perform the DB query and load all of the objects into memory. It should be pretty rare that you need to do this, but one case is when you need to use the query results in more than one place in your templates. Converting to list and passing the list in your template context will perform the query only once instead of once for every place in your template you iterate.
If you need more details, Malcolm Treddinick's blog posts Queryset Implementation and More Django Queryset Notes provide some insight into how Django ORM queryset works.