Opened 14 years ago

Closed 13 years ago

Last modified 12 years ago

#12831 closed Uncategorized (fixed)

Use CACHE_MIDDLEWARE_KEY_PREFIX in template cache.

Reported by: bzed@… Owned by: nobody
Component: Core (Cache system) Version: 1.1
Severity: Normal Keywords:
Cc: bernd.zeimetz@…, andre.cruz@… Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Running two django instances with the same memcached as cache
backend might result in displaying the wrong template from the cache
in case we have template files with the same name but a different
content.

ba95e1ae8fb810bbc4e9a2579cff3620df7300f5
diff --git a/Django-1.1.1/django/templatetags/cache.py b/Django-1.1.1/django/templatetags/cache.py
index 387dd87..6392731 100644
--- a/Django-1.1.1/django/templatetags/cache.py
+++ b/Django-1.1.1/django/templatetags/cache.py
@@ -1,3 +1,4 @@
+from django.conf import settings
 from django.template import Library, Node, TemplateSyntaxError, Variable, VariableDoesNotExist
 from django.template import resolve_variable
 from django.core.cache import cache
@@ -13,6 +14,7 @@ class CacheNode(Node):
         self.expire_time_var = Variable(expire_time_var)
         self.fragment_name = fragment_name
         self.vary_on = vary_on
+        self.key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
 
     def render(self, context):
         try:
@@ -25,7 +27,7 @@ class CacheNode(Node):
             raise TemplateSyntaxError('"cache" tag got a non-integer timeout value: %r' % expire_time)
         # Build a unicode key for this fragment and all vary-on's.
         args = md5_constructor(u':'.join([urlquote(resolve_variable(var, context)) for var in self.vary_on]))
-        cache_key = 'template.cache.%s.%s' % (self.fragment_name, args.hexdigest())
+        cache_key = 'template.cache.%s.%s.%s' % (self.key_prefix, self.fragment_name, args.hexdigest())
         value = cache.get(cache_key)
         if value is None:
             value = self.nodelist.render(context)

As various other applications which use the caching functions of django might run into the same issue, it could make sense to add the CACHE_MIDDLEWARE_KEY_PREFIX to the key at a different place, next to the backend so all keys of the instance will use it.

Change History (8)

comment:1 by anonymous, 14 years ago

Cc: bernd.zeimetz@… added

comment:2 by Alex Gaynor, 14 years ago

Triage Stage: UnreviewedDesign decision needed

This isn't in middleware though, so this doesnt seem semantically correct.

comment:3 by bzed, 14 years ago

As I've described on my blog post we're using our own cache backend now, which is based on the original memcached backend. In my opinion this issue really needs a design decision.

comment:4 by Archatas, 14 years ago

I've ran into the same problem running about six different Django websites on the same server which reuse some templates. In my opinion this change is crucial and maybe later CACHE_MIDDLEWARE_KEY_PREFIX can be changed to CACHE_KEY_PREFIX for logical consistency.

comment:5 by André Cruz, 14 years ago

Cc: andre.cruz@… added

comment:6 by André Cruz, 14 years ago

I also thought the key prefix would be applied to all operations involving the "cache" backend. It makes sense.

comment:7 by otherjacob, 13 years ago

Resolution: fixed
Status: newclosed

This use-case should be addressed in #13795 (pass in a site/instance-specific prefix into CACHES[cache_name]KEY_PREFIX).

comment:8 by nd.nguyen@…, 12 years ago

Easy pickings: unset
Severity: Normal
Type: Uncategorized
UI/UX: unset

You modify the cache file in django directly.
I am wondering if we overwrite file in my source code instead of change file in django. It's too dangerous. Any suggestion in this case? Tks :)

Note: See TracTickets for help on using tickets.
Back to Top