Why does django not hit the database when we try to access queryset object attributes?

Knowing that QuerySets are lazy, and a db query is made only when we try to access the queryset, I noticed that a db query is not made even if we iteratively try to access queryset object attributes (however, a query is made when we try to access the object itself). So a sample example for demonstration purposes.

from django.db import connection, reset_queries

reset_queries()
tests=Test.objects.filter(is_test=True)
print(len(connection.queries)) # returns 0
for obj in tests:
    print(obj.id)
    print(obj.is_test)
print(len(connection.queries)) # returns 0 again

The attributes are correctly printed, but how can they if it shows that a no query was made? Again if we do print(obj) instead, a query will be made. Any explanation is appreciated.

In your example, it hits the database only once, at:

for obj in tests:
    ...

Is where the QuerySet is evaluated. From that point forward when accessing objects you are not querying the database, but rather using the QuerySet fetched data.

Back to Top