Search code examples
djangodjango-orm

Why are Django related object queries not cached?


I have the following unit test:

def test_cache(self):
    with self.assertNumQueries(1):
        print(database.records.all())
        print(database.records.all())
        print(database.records.all())

The test fails because 3 queries are made:

Captured queries were:
1. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
2. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21
3. SELECT "store_record"."id", "store_record"."key", "store_record"."database_id", "store_record"."user_id", "store_record"."organization_id", "store_record"."data", "store_record"."created_at", "store_record"."updated_at" FROM "store_record" WHERE "store_record"."database_id" = '7d86d143-9e4e-4420-801c-3d3c5e6875fb'::uuid LIMIT 21

Why is the records field not cached? What is telling Django to do refetch the data from the database?


Solution

  • As documented :

    As well as caching of the whole QuerySet, there is caching of the result of attributes on ORM objects. In general, attributes that are not callable will be cached. For example, assuming the example blog models:

     entry = Entry.objects.get(id=1)
     entry.blog  # Blog object is retrieved at this point
     entry.blog  # cached version, no DB access   But in general, callable attributes cause DB lookups every time:
    
     entry = Entry.objects.get(id=1)
     entry.authors.all()  # query performed
     entry.authors.all()  # query performed again
    

    But this is not problem as if you need to access authors ( store_records in your case) you would properly use prefetch_related