Django 查询在被调用后是否保存其结果?
我正在尝试确定一个简单的缓存技巧是否真的有用。我知道 Django 查询集懒于提高效率,但我想知道它们是否在调用数据后保存查询结果。
例如,如果我有两个模型:
class Klass1(models.Model):
k2 = models.ForeignKey('Klass2')
class Klass2(models.Model):
# Model Code ...
@property
def klasses(self):
self.klasses = Klass1.objects.filter(k2=self)
return self.klasses
并且我在某处调用 klass_2_instance.klasses[:] ,则访问数据库并返回查询。我想知道如果我再次调用 klass_2_instance.klasses ,数据库会被第二次访问,还是 django 查询会保存第一次调用的结果?
I'm trying to determine whether or not a simple caching trick will actually be useful. I know Django querysets are lazy to improve efficiency, but I'm wondering if they save the result of their query after the data has been called.
For instance, if I have two models:
class Klass1(models.Model):
k2 = models.ForeignKey('Klass2')
class Klass2(models.Model):
# Model Code ...
@property
def klasses(self):
self.klasses = Klass1.objects.filter(k2=self)
return self.klasses
And I call klass_2_instance.klasses[:]
somewhere, then the database is accessed and returns a query. I'm wondering if I call klass_2_instance.klasses
again, will the database be accessed a second time, or will the django query save the result from the first call?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Django 不会为你缓存它。
您可以只执行 self.klass1_set.all(),而不是 Klass1.objects.filter(k2=self)。
因为 Django 总是在 1-n 关系的多方中创建一个集合。
我猜这种缓存很复杂,因为它应该记住所有使用的过滤器、排除和 order_by 。尽管可以使用任何精心设计的哈希来完成,但您至少应该有一个参数来禁用缓存。
如果您想要任何缓存,您可以这样做:
当您在所有相关对象中循环多次时,这非常有用。对我来说,当我需要循环多次时,这种情况经常发生在模板中。
Django will not cache it for you.
Instead of Klass1.objects.filter(k2=self), you could just do self.klass1_set.all().
Because Django always create a set in the many side of 1-n relations.
I guess this kind of cache is complicated because it should remember all filters, excludes and order_by used. Although it could be done using any well designed hash, you should at least have a parameter to disable cache.
If you would like any cache, you could do:
This is very useful when you loop many times in all related objects. For me it often happens in template, when I need to loop more than one time.
Django 不缓存此查询。
转发 FK 关系 - 即给定一个
Klass
对象klass
,执行klass.k2
- 是< /em> 在第一次查找后缓存。但相反,您在这里所做的 - 实际上通常拼写为klass2.klass_set.all()
- 不被缓存。您可以轻松地记住它:(
请注意,您现有的代码将不起作用,因为您正在使用属性覆盖方法
klasses
。)This query isn't cached by Django.
The forwards FK relationship - ie given a
Klass
objectklass
, doingklass.k2
- is cached after the first lookup. But the reverse, which you're doing here - and which is actually usually spelledklass2.klass_set.all()
- is not cached.You can easily memoize it:
(Note that your existing code won't work, as you're overriding the method
klasses
with an attribute.)如果您想要透明缓存查询集,请尝试使用 johnny-cache。
Try using johnny-cache if you want transparent caching of querysets.