According to (my reading of) the official dox here:
https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated
a Django QuerySet should be cached when you evaluate it. But that doesn’t seem to be the case. In the example that follows, TrackingImport is a model with a very large table behind it. (Output slightly edited for brevity.)
recs = TrackingImport.objects.filter(...stuff...)
In [102]: time(recs[0])
Wall time: 1.84 s
In [103]: time(recs[0])
Wall time: 1.84 s
Calling len() seems to work as advertised:
In [104]: len(recs)
Out[104]: 1823
In [105]: time(recs[0])
Wall time: 0.00 s
I don’t get why dereferencing the array didn’t cache the QuerySet results. It had to evaluate it, right? So what am I missing?
You can go through the source code(django.db.model.query), then you’ll be clear, here’s django 1.3.4’s query.py,
When you not iterate through the query set, the _result_cache is None, then when you invoke resc[0], it will just skip to following lines,
You’ll find that, in this case, the _result_cache is not being set. That’s why the duration of multiple resc[0] costs same time.
After you invoke len(resc), you can find source code,
You can see the _result_cache has values, then you invoke recs[0], it will just use the cache,
The souce code never lies, so it’s better to read the souce code when you don’t find your answer in documents.