Lazy loading relationships in Django (and other MV

2019-06-23 02:02发布

问题:

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?

回答1:

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.