Ticket #6586: extend_test.py

File extend_test.py, 3.9 KB (added by fredd4, 16 years ago)

Performance extends test

Line 
1#!/usr/bin/env python
2
3import sys, os
4from datetime import datetime, timedelta
5
6sys.path.append("../")
7sys.path.append(".")
8
9os.environ[ "DJANGO_SETTINGS_MODULE" ] = "settings"
10
11from django.template import loader, Context
12from timeit import Timer
13from django.template.loader_tags import *
14from django import template
15
16register = Library()
17
18class ExtendsNode(Node):
19 must_be_first = True
20
21 def __init__(self, nodelist, parent_name, parent_name_expr, template_dirs=None):
22 self.nodelist = nodelist
23 self.parent_name, self.parent_name_expr = parent_name, parent_name_expr
24 self.template_dirs = template_dirs
25 self.compiled_parent = None
26
27 def __repr__(self):
28 if self.parent_name_expr:
29 return "<ExtendsNode: extends %s>" % self.parent_name_expr.token
30 return '<ExtendsNode: extends "%s">' % self.parent_name
31
32 def get_parent(self, context):
33 if self.parent_name_expr:
34 self.parent_name = self.parent_name_expr.resolve(context)
35 parent = self.parent_name
36 if not parent:
37 error_msg = "Invalid template name in 'extends' tag: %r." % parent
38 if self.parent_name_expr:
39 error_msg += " Got this from the '%s' variable." % self.parent_name_expr.token
40 raise TemplateSyntaxError, error_msg
41 if hasattr(parent, 'render'):
42 return parent # parent is a Template object
43 try:
44 source, origin = find_template_source(parent, self.template_dirs)
45 except TemplateDoesNotExist:
46 raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent
47 else:
48 return get_template_from_string(source, origin, parent)
49
50 def process_parent( self, context ):
51 compiled_parent = self.get_parent(context)
52 pos = 0
53 while isinstance(compiled_parent.nodelist[pos], TextNode):
54 pos += 1
55 parent_is_child = isinstance(compiled_parent.nodelist[pos], ExtendsNode)
56 parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)])
57 for block_node in self.nodelist.get_nodes_by_type(BlockNode):
58 try:
59 parent_block = parent_blocks[block_node.name]
60 except KeyError:
61 if parent_is_child:
62 compiled_parent.nodelist[pos].nodelist.append(block_node)
63 else:
64 parent_block.parent = block_node.parent
65 parent_block.add_parent(parent_block.nodelist)
66 parent_block.nodelist = block_node.nodelist
67 return compiled_parent
68
69 def render(self, context):
70 if self.compiled_parent:
71 compiled_parent = self.compiled_parent
72 else:
73 compiled_parent = self.process_parent(context)
74 # cache it, if static
75 if self.parent_name:
76 self.compiled_parent = compiled_parent
77
78 return compiled_parent.render(context)
79
80
81@register.tag
82def extends(parser, token):
83 bits = token.contents.split()
84 if len(bits) != 2:
85 raise TemplateSyntaxError, "'%s' takes one argument" % bits[0]
86 parent_name, parent_name_expr = None, None
87 if bits[1][0] in ('"', "'") and bits[1][-1] == bits[1][0]:
88 parent_name = bits[1][1:-1]
89 else:
90 parent_name_expr = parser.compile_filter(bits[1])
91 nodelist = parser.parse()
92 if nodelist.get_nodes_by_type(ExtendsNode):
93 raise TemplateSyntaxError, "'%s' cannot appear more than once in the same template" % bits[0]
94 return ExtendsNode(nodelist, parent_name, parent_name_expr)
95
96
97t = loader.get_template('registration/password_reset_done.html')
98
99def x():
100 return t.render( Context() )
101
102def test():
103 timer = Timer("x()", "from __main__ import x")
104 print "time: %s" % (timer.timeit(1000) )
105
106test()
107
108# turn on modified tag, and reload variable t
109template.builtins.append( register )
110t = loader.get_template('registration/password_reset_done.html')
111
112test()
Back to Top