Moved caching of contentlets/contentreferences so that (for example) a page with...
[philo.git] / philo / templatetags / containers.py
index 2c55034..3956f1d 100644 (file)
@@ -19,16 +19,28 @@ CONTAINER_CONTEXT_KEY = 'philo_container_context'
 
 class ContainerContext(object):
        def __init__(self, page):
-               contentlet_specs, contentreference_specs = page.template.containers
-               
-               contentlets = page.contentlets.filter(name__in=contentlet_specs)
-               self.contentlets = dict(((c.name, c) for c in contentlets))
-               
-               q = Q()
-               for name, ct in contentreference_specs.items():
-                       q |= Q(name=name, content_type=ct)
-               references = page.contentreferences.filter(q)
-               self.references = dict(((c.name, c) for c in references))
+               self.page = page
+       
+       def get_contentlets(self):
+               if not hasattr(self, '_contentlets'):
+                       self._contentlets = dict(((c.name, c) for c in self.page.contentlets.all()))
+               return self._contentlets
+       
+       def get_references(self):
+               if not hasattr(self, '_references'):
+                       references = self.page.contentreferences.all()
+                       self._references = {}
+                       contents = {}
+                       for c in references:
+                               ct = ContentType.objects.get_for_id(c.content_type_id)
+                               self.references[(c.name, ct)] = c
+                               contents.setdefault(ct, {})[c.content_id] = c
+                       
+                       for ct in contents:
+                               objs = ct.model_class().objects.filter(pk__in=contents[ct])
+                               for obj in objs:
+                                       contents[ct][obj.pk].content = obj
+               return self._references
 
 
 class ContainerNode(template.Node):
@@ -38,32 +50,30 @@ class ContainerNode(template.Node):
                self.references = references
        
        def render(self, context):
-               content = settings.TEMPLATE_STRING_IF_INVALID
-               if 'page' in context:
-                       container_content = self.get_container_content(context)
-               else:
-                       container_content = None
+               container_content = self.get_container_content(context)
                
                if self.as_var:
                        context[self.as_var] = container_content
                        return ''
                
-               if not container_content:
-                       return ''
-               
                return container_content
        
        def get_container_content(self, context):
                try:
                        container_context = context.render_context[CONTAINER_CONTEXT_KEY]
                except KeyError:
-                       container_context = ContainerContext(context['page'])
+                       try:
+                               page = context['page']
+                       except KeyError:
+                               return settings.TEMPLATE_STRING_IF_INVALID
+                       
+                       container_context = ContainerContext(page)
                        context.render_context[CONTAINER_CONTEXT_KEY] = container_context
                
                if self.references:
                        # Then it's a content reference.
                        try:
-                               contentreference = container_context.references[(self.name, self.references)]
+                               contentreference = container_context.get_references()[(self.name, self.references)]
                        except KeyError:
                                content = ''
                        else:
@@ -71,7 +81,7 @@ class ContainerNode(template.Node):
                else:
                        # Otherwise it's a contentlet.
                        try:
-                               contentlet = container_context.contentlets[self.name]
+                               contentlet = container_context.get_contentlets()[self.name]
                        except KeyError:
                                content = ''
                        else: