How do I delete a cached template fragment in Django?
Asked Answered
S

3

11

Previously, I had set up a cached chunk of HTML in my Django template as follows.

{% load cache %}            
    {% cache 10000 courseTable %} <!-- Cached HTML --> {% endcache %}

Now, I have updated this cached content and want to refresh it. I tried changing the time to no avail:

{% load cache %}            
    {% cache 0 courseTable %} <!-- Updated Cached HTML --> {% endcache %}

In this case, the page still displays the old cached HTML.

I also tried removing the template tags associated with caching and reinserting them. However, in this case, the content just reverts to the originally cached content after I reinsert the cache template tags.

What can I do? I do not want to wait about 2 hours to reload my cache.

Separatist answered 28/5, 2012 at 3:19 Comment(3)
Wait, I can just do that with python-memcache?Separatist
How do I just empty the cache? I can afford to simply empty Memcache entirely.Separatist
There are only two hard problems in computer science...Garter
P
15

For Django 1.6+ and from the Django Documentation you could just generate the key of the partial you're looking for and delete it:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key

# cache key for {% cache 500 sidebar username %} templatetag
key = make_template_fragment_key('sidebar', [username])
cache.delete(key) # invalidates cached template fragment

You just need to call make_template_fragment_key with your previously defined courseTable argument.

Petersburg answered 9/3, 2017 at 21:39 Comment(1)
Line 4 of your code sample is not valid, I guess meant to be a comment, however it threw me off thinking I was looking at semi-pseudo-code, and couldn't get this to work. I think it's important to highlight that [username] really should be a list. Maybe it's just me though :)Trauner
T
8

If you could afford to empty memcached entirely, run flush_all cmd or simply

from django.core.cache import cache
cache.clear()

Or else you have to generate the cache-key manually. The timeout will not be refreshed until the key is expired.

Troupe answered 28/5, 2012 at 4:47 Comment(1)
This might make sense for some cases, but completely flushing cache is not a good alternative to selectively flush whenever possible and for the original question, django's make_template_fragment_key is probably a better approachClaptrap
H
2

Prior to Django 1.6, the cache template tag built its cache keys more-or-less in the body of the tag's definition (see here). From 1.6 onward, template fragment cache keys have been built using the django.core.cache.utils.make_template_fragment_key function (see here).

In any case, you can delete a specific cached fragment by using or defining make_template_fragment_key to get its cache key like so:

from __future__ import unicode_literals

import hashlib
from django.core.cache import cache
from django.utils.encoding import force_bytes
from django.utils.http import urlquote

TEMPLATE_FRAGMENT_KEY_TEMPLATE = 'template.cache.%s.%s'


def make_template_fragment_key(fragment_name, vary_on=None):
    if vary_on is None:
        vary_on = ()
    key = ':'.join(urlquote(var) for var in vary_on)
    args = hashlib.md5(force_bytes(key))
    return TEMPLATE_FRAGMENT_KEY_TEMPLATE % (fragment_name, args.hexdigest())


def delete_cached_fragment(fragment_name, *args):
    cache.delete(make_template_fragment_key(fragment_name, args or None))


delete_cached_fragment('my_fragment', 'other', 'vary', 'args')

This code is directly copied from the django codebase so this license and copyright applies.

Hodess answered 18/1, 2015 at 23:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.