Ticket #3453: resolve-variable.2.patch
| File resolve-variable.2.patch, 15.4 kB (added by Brian Harring <ferringb@gmail.com>, 2 years ago) |
|---|
-
django/contrib/admin/templatetags/admin_modify.py
old new 71 71 default = None 72 72 73 73 def __init__(self, bound_field_var): 74 self.bound_field_var = bound_field_var74 self.bound_field_var = template.Variable(bound_field_var) 75 75 76 76 def get_nodelist(cls, klass): 77 77 if klass not in cls.nodelists: … … 95 95 get_nodelist = classmethod(get_nodelist) 96 96 97 97 def render(self, context): 98 bound_field = template.resolve_variable(self.bound_field_var,context)98 bound_field = self.bound_field_var.resolve(context) 99 99 100 100 context.push() 101 101 context['bound_field'] = bound_field … … 155 155 156 156 class EditInlineNode(template.Node): 157 157 def __init__(self, rel_var): 158 self.rel_var = rel_var158 self.rel_var = template.Variable(rel_var) 159 159 160 160 def render(self, context): 161 relation = template.resolve_variable(self.rel_var,context)161 relation = self.rel_var.resolve(context) 162 162 context.push() 163 163 if relation.field.rel.edit_inline == models.TABULAR: 164 164 bound_related_object_class = TabularBoundRelatedObject -
django/contrib/comments/templatetags/comments.py
old new 18 18 ratings_optional=False, ratings_required=False, rating_options='', 19 19 is_public=True): 20 20 self.content_type = content_type 21 if obj_id_lookup is not None: 22 obj_id_lookup = template.Variable 21 23 self.obj_id_lookup_var, self.obj_id, self.free = obj_id_lookup_var, obj_id, free 22 24 self.photos_optional, self.photos_required = photos_optional, photos_required 23 25 self.ratings_optional, self.ratings_required = ratings_optional, ratings_required … … 31 33 context.push() 32 34 if self.obj_id_lookup_var is not None: 33 35 try: 34 self.obj_id = template.resolve_variable(self.obj_id_lookup_var,context)36 self.obj_id = self.obj_id_lookup_var.resolve(context) 35 37 except template.VariableDoesNotExist: 36 38 return '' 37 39 # Validate that this object ID is valid for this content-type. … … 74 76 class CommentCountNode(template.Node): 75 77 def __init__(self, package, module, context_var_name, obj_id, var_name, free): 76 78 self.package, self.module = package, module 79 if context_var_name is not None: 80 context_var_name = template.Variable(context_var_name) 77 81 self.context_var_name, self.obj_id = context_var_name, obj_id 78 82 self.var_name, self.free = var_name, free 79 83 … … 81 85 from django.conf import settings 82 86 manager = self.free and FreeComment.objects or Comment.objects 83 87 if self.context_var_name is not None: 84 self.obj_id = template.resolve_variable(self.context_var_name,context)88 self.obj_id = self.context_var_name.resolve(context) 85 89 comment_count = manager.filter(object_id__exact=self.obj_id, 86 90 content_type__app_label__exact=self.package, 87 91 content_type__model__exact=self.module, site__id__exact=settings.SITE_ID).count() … … 91 95 class CommentListNode(template.Node): 92 96 def __init__(self, package, module, context_var_name, obj_id, var_name, free, ordering, extra_kwargs=None): 93 97 self.package, self.module = package, module 98 if context_var_name is not None: 99 context_var_name = template.Variable(context_var_name) 94 100 self.context_var_name, self.obj_id = context_var_name, obj_id 95 101 self.var_name, self.free = var_name, free 96 102 self.ordering = ordering … … 101 107 get_list_function = self.free and FreeComment.objects.filter or Comment.objects.get_list_with_karma 102 108 if self.context_var_name is not None: 103 109 try: 104 self.obj_id = template.resolve_variable(self.context_var_name,context)110 self.obj_id = self.context_var_name.resolve(context) 105 111 except template.VariableDoesNotExist: 106 112 return '' 107 113 kwargs = { -
django/template/__init__.py
old new 91 91 tag_re = re.compile('(%s.*?%s|%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), 92 92 re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END), 93 93 re.escape(COMMENT_TAG_START), re.escape(COMMENT_TAG_END))) 94 # matches if the string is valid number95 number_re = re.compile(r'[-+]?(\d+|\d*\.\d+)$')96 94 97 95 # global dictionary of libraries that have been loaded using get_library 98 96 libraries = {} … … 562 560 elif constant_arg is not None: 563 561 args.append((False, constant_arg.replace(r'\"', '"'))) 564 562 elif var_arg: 565 args.append((True, var_arg))563 args.append((True, Variable(var_arg))) 566 564 filter_func = parser.find_filter(filter_name) 567 565 self.args_check(filter_name,filter_func, args) 568 566 filters.append( (filter_func,args)) 569 567 upto = match.end() 570 568 if upto != len(token): 571 569 raise TemplateSyntaxError, "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token) 572 self.var, self.filters = var, filters 570 self.filters = filters 571 self.var = Variable(var) 573 572 574 573 def resolve(self, context, ignore_failures=False): 575 574 try: 576 obj = resolve_variable(self.var,context)575 obj = self.var.resolve(context) 577 576 except VariableDoesNotExist: 578 577 if ignore_failures: 579 578 obj = None … … 593 592 if not lookup: 594 593 arg_vals.append(arg) 595 594 else: 596 arg_vals.append( resolve_variable(arg,context))595 arg_vals.append(arg.resolve(context)) 597 596 obj = func(obj, *arg_vals) 598 597 return obj 599 598 … … 652 651 653 652 (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.') 654 653 """ 655 if number_re.match(path): 656 number_type = '.' in path and float or int 657 current = number_type(path) 658 elif path[0] in ('"', "'") and path[0] == path[-1]: 659 current = path[1:-1] 660 else: 654 return Variable(path).resolve(context) 655 656 class LiteralVariable(object): 657 658 def __init__(self, val): 659 self.val = val 660 661 def resolve(self, context): 662 return self.val 663 664 def __str__(self): 665 return self.val 666 667 def Variable(val): 668 try: 669 # note we're not catching OverflowError here; point of debate on how best to handle that... 670 current = float(val) 671 if '.' not in val: 672 # downside to this approach is that 1e07 becomes an int; float may be preferable still. 673 current = int(current) 674 elif val[-1] == '.': 675 # 2. is invalid 676 raise ValueError 677 return LiteralVariable(current) 678 except ValueError: 679 pass 680 if val[0] in "\"'" and val[0] == val[-1]: 681 return LiteralVariable(val[1:-1]) 682 return ChainedLookupVariable(val) 683 684 class ChainedLookupVariable(object): 685 686 def __init__(self, val): 687 self.lookups = tuple(val.split(VARIABLE_ATTRIBUTE_SEPARATOR)) 688 689 def resolve(self, context): 661 690 current = context 662 bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR) 663 while bits: 691 for bit in self.lookups: 664 692 try: # dictionary lookup 665 current = current[bit s[0]]693 current = current[bit] 666 694 except (TypeError, AttributeError, KeyError): 667 695 try: # attribute lookup 668 current = getattr(current, bit s[0])696 current = getattr(current, bit) 669 697 if callable(current): 670 698 if getattr(current, 'alters_data', False): 671 699 current = settings.TEMPLATE_STRING_IF_INVALID … … 683 711 raise 684 712 except (TypeError, AttributeError): 685 713 try: # list-index lookup 686 current = current[int(bit s[0])]714 current = current[int(bit)] 687 715 except (IndexError, # list index out of range 688 716 ValueError, # invalid literal for int() 689 KeyError, # current is a dict without `int(bit s[0])` key717 KeyError, # current is a dict without `int(bit)` key 690 718 TypeError, # unsubscriptable object 691 719 ): 692 raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bit s[0], current)) # missing attribute720 raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bit, current)) # missing attribute 693 721 except Exception, e: 694 722 if getattr(e, 'silent_variable_failure', False): 695 723 current = settings.TEMPLATE_STRING_IF_INVALID 696 724 else: 697 725 raise 698 del bits[0] 699 return current 726 return current 727 728 def __str__(self): 729 return VARIABLE_ATTRIBUTE_SEPARATOR.join(self.lookups) 700 730 701 731 class Node(object): 702 732 def render(self, context): … … 867 897 868 898 class SimpleNode(Node): 869 899 def __init__(self, vars_to_resolve): 870 self.vars_to_resolve = vars_to_resolve900 self.vars_to_resolve = map(Variable, vars_to_resolve) 871 901 872 902 def render(self, context): 873 resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] 874 return func(*resolved_vars) 903 return func(*[var.resolve(context) for var in self.vars_to_resolve]) 875 904 876 905 compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode) 877 906 compile_func.__doc__ = func.__doc__ … … 889 918 890 919 class InclusionNode(Node): 891 920 def __init__(self, vars_to_resolve): 892 self.vars_to_resolve = vars_to_resolve921 self.vars_to_resolve = map(Variable, vars_to_resolve) 893 922 894 923 def render(self, context): 895 resolved_vars = [ resolve_variable(var,context) for var in self.vars_to_resolve]924 resolved_vars = [var.resolve(context) for var in self.vars_to_resolve] 896 925 if takes_context: 897 926 args = [context] + resolved_vars 898 927 else: -
django/template/defaulttags.py
old new 1 1 "Default tags used by the template system, available to all templates." 2 2 3 from django.template import Node, NodeList, Template, Context, resolve_variable3 from django.template import Node, NodeList, Template, Context, Variable 4 4 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END 5 5 from django.template import get_library, Library, InvalidTemplateLibrary 6 6 from django.conf import settings … … 48 48 49 49 class FirstOfNode(Node): 50 50 def __init__(self, vars): 51 self.vars = vars51 self.vars = map(Variable, vars) 52 52 53 53 def render(self, context): 54 54 for var in self.vars: 55 55 try: 56 value = resolve_variable(var,context)56 value = var.resolve(context) 57 57 except VariableDoesNotExist: 58 58 continue 59 59 if value: … … 130 130 def __init__(self, nodelist, *varlist): 131 131 self.nodelist = nodelist 132 132 self._last_seen = None 133 self._varlist = varlist133 self._varlist = map(Variable, varlist) 134 134 135 135 def render(self, context): 136 136 if 'forloop' in context and context['forloop']['first']: … … 139 139 if self._varlist: 140 140 # Consider multiple parameters. 141 141 # This automatically behaves like a OR evaluation of the multiple variables. 142 compare_to = [ resolve_variable(var,context) for var in self._varlist]142 compare_to = [var.resolve(context) for var in self._varlist] 143 143 else: 144 144 compare_to = self.nodelist.render(context) 145 145 except VariableDoesNotExist: … … 158 158 159 159 class IfEqualNode(Node): 160 160 def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): 161 self.var1, self.var2 = var1, var2161 self.var1, self.var2 = Variable(var1), Variable(var2) 162 162 self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false 163 163 self.negate = negate 164 164 … … 167 167 168 168 def render(self, context): 169 169 try: 170 val1 = resolve_variable(self.var1,context)170 val1 = self.var1.resolve(context) 171 171 except VariableDoesNotExist: 172 172 val1 = None 173 173 try: 174 val2 = resolve_variable(self.var2,context)174 val2 = self.var2.resolve(context) 175 175 except VariableDoesNotExist: 176 176 val2 = None 177 177 if (self.negate and val1 != val2) or (not self.negate and val1 == val2): -
django/template/loader_tags.py
old new 1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable 2 2 from django.template import Library, Node 3 3 from django.template.loader import get_template, get_template_from_string, find_template_source 4 4 from django.conf import settings … … 99 99 100 100 class IncludeNode(Node): 101 101 def __init__(self, template_name): 102 self.template_name = template_name102 self.template_name = Variable(template_name) 103 103 104 104 def render(self, context): 105 105 try: 106 template_name = resolve_variable(self.template_name,context)106 template_name = self.template_name.resolve(context) 107 107 t = get_template(template_name) 108 108 return t.render(context) 109 109 except TemplateSyntaxError, e: -
django/templatetags/i18n.py
old new 1 from django.template import Node, resolve_variable1 from django.template import Node, Variable 2 2 from django.template import TemplateSyntaxError, TokenParser, Library 3 3 from django.template import TOKEN_TEXT, TOKEN_VAR 4 4 from django.utils import translation … … 32 32 33 33 class TranslateNode(Node): 34 34 def __init__(self, value, noop): 35 self.value = value35 self.value = Variable(value) 36 36 self.noop = noop 37 37 38 38 def render(self, context): 39 value = resolve_variable(self.value,context)39 value = self.value.resolve(context) 40 40 if self.noop: 41 41 return value 42 42 else:
