简短的回答是肯定的,但是您将无法在不引起另一个数据库调用的情况下使用 QuerySet 过滤器。您需要遍历返回的结果以避免数据库命中。这取决于您是否要根据返回结果的大小和新过滤查询的查询时间来执行此操作。
如QuerySet
文档中所述,过滤后的 QuerySet 返回一个不受原始 QuerySet 约束的新 QuerySet。
要进一步了解情况,您可以查看信号johnny.signals.qc_hit
并johnny.signals.qc_miss
查看它何时进行数据库调用。 信号是一种将回调绑定到某些事件的 django 机制。在这种情况下,Johnny Cache 暴露了这两个有用的信号。
我创建了一个简单的应用程序来测试它并帮助演示这种行为。
模型.py
from django.db import models
class TestModel(models.Model):
prop_a = models.TextField()
prop_b = models.TextField()
def __unicode__(self):
return "{} {}".format(self.prop_a, self.prop_b)
视图.py
from django.dispatch import receiver
from django.http import HttpResponse
from johnny.signals import qc_hit, qc_miss
from models import TestModel
def index(self):
objs = TestModel.objects.all()
print objs
print objs.filter(prop_a='a') #Causes another database or cache hit
return HttpResponse("success")
def generate(self):
generate_data()
return HttpResponse("generated")
def generate_data():
properties = [ 'a', 'b', 'c', 'd', 'e']
for i in xrange(len(properties)):
for j in xrange(len(properties)):
test_model = TestModel(prop_a=properties[i], prop_b=properties[j])
test_model.save()
@receiver(qc_hit)
def cache_hit(sender, **kwargs):
print "cache hit"
@receiver(qc_miss)
def cache_miss(sender, **kwargs):
print "cache miss"
由于 Johnny Cache 是通过中间件完成的,因此您需要通过视图对其进行测试,因为它从请求到响应都会发生。在上面的例子中,我们有一个非常简单的模型,我们正在查看所有TestModel
对象,然后是过滤结果。输出将显示每一个最初导致缓存未命中,然后是缓存命中。它们不相关,被视为两个单独的查询。
但是,如果你做类似的事情
objs = TestModel.objects.all()
result = []
for obj in objs:
if obj.prop_a == 'a':
result.append(obj)
您只会看到对数据库/johnny 缓存的一次命中。显然,这会得到您想要的结果,但可能会或可能不会比另一个查询慢,具体取决于初始查询的大小。
我希望这有助于回答您的问题,并为您提供一种了解缓存如何进一步工作的方法。