The short answer is yes, but you won't be able to use QuerySet filters without causing another database call. You'll need to iterate through the returned results to avoid a database hit. It depends on whether you want to do this or not based on the size of the returned results and the query time for the new filtered query.
As mentioned in the QuerySet
documentation, a filtered QuerySet returns a new QuerySet that isn't bound by the original.
To understand the situation further, you can look at the signals johnny.signals.qc_hit
and johnny.signals.qc_miss
to see when it is making a database call. Signals are a django mechanism to bind callbacks to certain events. In this case, Johnny Cache exposes these two useful signals.
I created a simple application to test it out and to help demonstrate this behavior.
models.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)
views.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"
As Johnny Cache is done through a middleware, you'll need to test it through a view since it happens from request to response. In the case above, we have a very simple model that we're looking at all the TestModel
objects and then a filtered result. The output will show the each one initially causing a cache miss and then subsequently a cache hit. They aren't related and are considered two separate queries.
However, if you do something like
objs = TestModel.objects.all()
result = []
for obj in objs:
if obj.prop_a == 'a':
result.append(obj)
You'll only see one hit to the database / johnny cache. Obviously this gets your desired result, but may or may not be slower than another query depending on the size of the initial query.
I hope this helps answer your question as well as give you an approach to understand how the caching works further.