Django的cached_property未生效仍重复查询数据库问题求助
问题原因与解决方案
问题原因
- 你对
@cached_property的语法使用没有错误,但它缓存的是QuerySet对象,而非查询后的实际结果数据。 - Django的QuerySet是惰性执行机制:只有当你实际获取它的内容(比如遍历、转成列表、访问元素、在终端直接输出等)时,才会真正触发数据库查询。
- 每次执行
person = People.objects.get(pk=1)都会生成全新的People实例,该实例的tags属性尚未被缓存,访问时会创建新的QuerySet;一旦你对这个QuerySet进行求值操作,就会触发Tags表的查询,因此总共产生两次数据库请求(一次查People表,一次查Tags表)。
解决方案
方案1:缓存查询结果而非QuerySet
将QuerySet转换为具体的结果列表后再返回,让cached_property直接缓存查询后的结果,后续访问不会再触发数据库查询:
from django.utils.functional import cached_property class People(models.Model): name = models.CharField(max_length=255) @cached_property def tags(self): # 用list()强制立即执行查询并缓存结果 return list(Tag.objects.filter(person=self, type="A"))
方案2:预取关联数据(推荐)
如果你希望在获取People实例时就一次性拉取关联的Tags数据,可以使用prefetch_related配合Prefetch对象,实现一次查询获取所有需要的数据:
from django.db.models import Prefetch # 查询时预取符合条件的Tags,并赋值给tags属性 person = People.objects.prefetch_related( Prefetch('tag_set', queryset=Tag.objects.filter(type="A"), to_attr='tags') ).get(pk=1)
后续访问person.tags时,直接使用预取的结果,不会产生额外的数据库查询。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

