Почему запросы к связанным с Django объектам не кэшируются?
У меня есть следующий модульный тест:
def test_cache(self):
with self.assertNumQueries(1):
print(database.records.all())
print(database.records.all())
print(database.records.all())
Тест провален, потому что сделано 3 запроса:
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
Почему поле записей не кэшируется? Что указывает Django на необходимость повторной выборки данных из базы данных?
Как задокументировано :
Помимо кэширования всего набора QuerySet, существует кэширование результатов атрибутов объектов ORM. Как правило, кэшируются атрибуты, которые не вызываются, будут кэшироваться. Например, если взять пример блога 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
Но это не проблема, так как если вам нужно получить доступ к авторам (store_records в вашем случае), вы должны правильно использовать prefetch_related