I've got a site where some pages take really long to calculate and
display (~40s), so I've turned on the caching and it works like a
breeze. I'm amazed.
This is a data-analysis site, and after I change some parameters, I want
to clear the cache for one of the views. How can I force a view to
expire?
Reading the docs http://www.djangoproject.com/documentation/cache/ I
think that I need to use the vary_on_headers, but I need to create a
custom header and modify it whenever my data gets modified. I just don't
know how to do it. Can you give me a hint?
--
Maciej Bliziński
http://automatthias.wordpress.com
Take a look at the example just above the "Upstream Caches"
paragraph. It shows how to delete a key (view) from the cache.
http://www.djangoproject.com/documentation/cache/#upstream-caches
Don
Hm... the keys look like:
views.decorators.cache.cache_page.myprefix./myproject/.d41d8cd98f00b204e9800998ecf8427e
It's fine, except the trailing MD5 sum. Is there a way to guess the key
of the view? Otherwise, I could use SQL to find everything that begins
with "views.decorators.cache.cache_page.myprefix./myproject/something/"
and nuke it, but I'd rather stay high-level.
How is your view retrieving the cached data in the first place, if it
doesn't know the key?
--
"May the forces of evil become confused on the way to your house."
-- George Carlin
To my understanding if you need to be able to manuallly get and clear
cached pages you'll need to use the view level caching, not the
middleware.
You're guessing right. Sorry for not being specific enough.
> To my understanding if you need to be able to manually get and clear
> cached pages you'll need to use the view level caching, not the
> middleware.
So I switched to per-view caching, according to the docs:
http://www.djangoproject.com/documentation/cache/#the-per-view-cache
from django.views.decorators.cache import cache_page
def slashdot_this(request):
...
slashdot_this = cache_page(slashdot_this, 60 * 15)
I removed the middleware references from the settings.
The keys still look the same, with the MD5-sum at the end. Do I need to
use the cache.set() and cache.get() methods then?
What you probably want is the low-level cache API, and use it to store
the results of your long-running calculations. Since you're setting the
entry in the cache the key generation is up to you. So you wont' be
caching at the page or view level, just specific pieces of data that
are resource-intensive, and the view will run on every request.
It's probably not a huge ordeal to extend/rewrite the caching
middleware to respond to signals and let you cache page level and clear
it by sending signals on data updates, but I don't think anything like
this is available out of the box. But maybe it is somehow, I'm not too
familiar with all the innards and parts available... you can see how
Django generates its keys in django.utils.cache.
I tried that and it works, thanks Todd.
Just a small gotcha-remark. I was storing the QuerySets directly after
calling them:
qs = cache.get(mykey)
if not qs:
qs = MyClass.objects.filter(...)
cache.set(mykey, qs, expiration)
And somehow it didn't speed-up the request processing... what was the
problem?
The QuerySets are lazy! I was storing unevaluated QuerySets!
I had a good laugh. :-)
I now store the whole response objects, because I had several expensive
queries and I didn't want to code caching of each of them separately.
Regards,
Maciej