Caching partial templates

71 views
Skip to first unread message

oron

unread,
Dec 13, 2005, 7:17:28 AM12/13/05
to Django users
coming from ROR where it's easy to cache partials (parts of templates)
I couldn't find a way to cache just parts of my template easily without
going back to the cache low level API.

What's the suggested strategy for caching for example the home page
which will be hit lots of times, in case where I use sessions and need
to display the "hello {{ user.name }}" somewhere etc.

Adrian Holovaty

unread,
Dec 14, 2005, 11:18:09 AM12/14/05
to django...@googlegroups.com

You could write a custom {% cache %} template tag that would cache
everything between it and {% endcache %} for a certain number of
seconds:

{% cache '500' %}
This will be cached for 500 seconds.
{% endcache %}

If you write it and submit a patch, we'd definitely consider adding
this to the Django distribution.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com | chicagocrime.org

Ian Holsman

unread,
Dec 15, 2005, 4:14:29 AM12/15/05
to django...@googlegroups.com
wouldn't you also need a cache-key as a parameter?

regards
Ian


--
I...@Holsman.net -- blog: http://feh.holsman.net/ -- PH: ++61-3-9877-0909

If everything seems under control, you're not going fast enough. -
Mario Andretti

Ian Maurer

unread,
Mar 22, 2006, 8:47:54 PM3/22/06
to django...@googlegroups.com

I created a custom cache template tag for partial/fragment caches. Its
probably a little to specific for my project for use in the framework,
but I think its a good starting point for others who find this thread.

For my purposes, I not only have an expiration time, but also a name
along with an unlimited number of "ids" that get resolved. Below is
the format of the tag:

{% load fragment_caching %}
{% cache <exptime> <name> [id args..] %}

For instance...

{% load fragment_caching %}
{% cache 500 sidebar object.id %}

.. sidebar for object ..

{% endcache %}

Here is the code for the module fragment_caching.py under my
templatetags module:

from django.core.template import Library, Node, TemplateSyntaxError,
resolve_variable
register = Library()

@register.tag(name="cache")
def do_cache(parser, token):
nodelist = parser.parse(('endcache',))

parser.delete_first_token()

args = token.contents.split()
if len(args) >= 3:
tag_name, expire_time, fragment_name = args[:3]
id_names = args[3:]
else:
raise TemplateSyntaxError("Invalid arguments to cache: %s" % args)

return CacheNode(nodelist, expire_time, fragment_name, id_names)

class CacheNode(Node):
def __init__(self, nodelist, expire_time, fragment_name, id_names):
self.nodelist = nodelist
self.expire_time = expire_time
self.fragment_name = fragment_name
self.id_names = id_names

def render(self, context):
cache_id = self.fragment_name
for id_name in self.id_names:
cache_id += ":%s" % resolve_variable(id_name, context)

from django.core.cache import cache
value = cache.get(cache_id)

if not value:
value = self.nodelist.render(context)
cache.set(cache_id, value, float(self.expire_time))

return value

Obviously you need to have cache enabled for this to work:

http://www.djangoproject.com/documentation/cache/

--
Ian Maurer

Reply all
Reply to author
Forward
0 new messages