How do I delete a cached template fragment in Django?

12k Views Asked by At

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.

3

There are 3 best solutions below

1
On

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.

0
On

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.

1
On

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.