Ticket #9154: #9154 - templates_optimizations.2.diff

File #9154 - templates_optimizations.2.diff, 5.4 KB (added by Kronuz, 6 years ago)

same as the previous but with deepcopy removed

  • django/template/loader_tags.py

     
    11from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
    2 from django.template import Library, Node, TextNode
    3 from django.template.loader import get_template, get_template_from_string, find_template_source
     2from django.template import Library, Node, NodeList, TextNode
     3from django.template.loader import get_template
    44from django.conf import settings
    55from django.utils.safestring import mark_safe
    66
     
    4343        self.nodelist = nodelist
    4444        self.parent_name, self.parent_name_expr = parent_name, parent_name_expr
    4545        self.template_dirs = template_dirs
     46        if self.parent_name_expr is None:
     47            self.compiled_parent = self.get_parent(context=None)
     48        else:
     49            self.compiled_parent = None
    4650
    4751    def __repr__(self):
    4852        if self.parent_name_expr:
     
    6165        if hasattr(parent, 'render'):
    6266            return parent # parent is a Template object
    6367        try:
    64             source, origin = find_template_source(parent, self.template_dirs)
     68            return get_template(parent, self.template_dirs)
    6569        except TemplateDoesNotExist:
    6670            raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent
    67         else:
    68             return get_template_from_string(source, origin, parent)
    6971
    7072    def render(self, context):
    71         compiled_parent = self.get_parent(context)
     73        if self.compiled_parent is not None:
     74            compiled_parent = self.compiled_parent
     75        else:
     76            compiled_parent = self.get_parent(context)
    7277        parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
     78        old_parent_nodelists = {}
     79        added_extended_blocknodes = []
    7380        for block_node in self.nodelist.get_nodes_by_type(BlockNode):
    7481            # Check for a BlockNode with this node's name, and replace it if found.
    7582            try:
     
    8693                        # If the first non-text node is an extends, handle it.
    8794                        if isinstance(node, ExtendsNode):
    8895                            node.nodelist.append(block_node)
     96                            added_extended_blocknodes.append(block_node.name)
    8997                        # Extends must be the first non-text node, so once you find
    9098                        # the first non-text node you can stop looking.
    9199                        break
     
    93101                # Keep any existing parents and add a new one. Used by BlockNode.
    94102                parent_block.parent = block_node.parent
    95103                parent_block.add_parent(parent_block.nodelist)
     104                old_parent_nodelists[block_node.name] = parent_block.nodelist
    96105                parent_block.nodelist = block_node.nodelist
    97         return compiled_parent.render(context)
     106        rendered_string = compiled_parent.render(context)
     107        # Restore every original parent nodelist to the state prior rendering it
     108        for node_name, nodelist in old_parent_nodelists.items():
     109            parent_blocks[node_name].nodelist = nodelist
     110        # Remove added BlockNodes to the parent's ExtendsNode
     111        for node in compiled_parent.nodelist:
     112            if not isinstance(node, TextNode):
     113                if isinstance(node, ExtendsNode):
     114                    node.nodelist = NodeList(filter(lambda n: not isinstance(n, BlockNode) or n.name not in added_extended_blocknodes, node.nodelist))
     115                break
     116        return rendered_string
    98117
    99118class ConstantIncludeNode(Node):
    100119    def __init__(self, template_path):
     
    156175    uses the literal value "base" as the name of the parent template to extend,
    157176    or ``{% extends variable %}`` uses the value of ``variable`` as either the
    158177    name of the parent template to extend (if it evaluates to a string) or as
    159     the parent tempate itelf (if it evaluates to a Template object).
     178    the parent template itself (if it evaluates to a Template object).
    160179    """
    161180    bits = token.split_contents()
    162181    if len(bits) != 2:
  • django/template/loader.py

     
    2727
    2828template_source_loaders = None
    2929
     30_template_cache = {}
     31
    3032class LoaderOrigin(Origin):
    3133    def __init__(self, display_name, loader, name, dirs):
    3234        super(LoaderOrigin, self).__init__(display_name)
     
    7375            pass
    7476    raise TemplateDoesNotExist, name
    7577
    76 def get_template(template_name):
     78def get_template(template_name, dirs=None):
    7779    """
    7880    Returns a compiled Template object for the given template name,
    7981    handling template inheritance recursively.
    8082    """
    81     source, origin = find_template_source(template_name)
    82     template = get_template_from_string(source, origin, template_name)
     83    if not settings.TEMPLATE_DEBUG and template_name in _template_cache:
     84        template = _template_cache[template_name]
     85    else:
     86        source, origin = find_template_source(template_name, dirs)
     87        template = get_template_from_string(source, origin, template_name)
     88        _template_cache[template_name] = template
    8389    return template
    8490
    8591def get_template_from_string(source, origin=None, name=None):
Back to Top