Code

Ticket #2082: more_robust_resolve_variable_in_template.diff

File more_robust_resolve_variable_in_template.diff, 3.8 KB (added by anonymous, 8 years ago)
Line 
1Index: django/template/__init__.py
2===================================================================
3--- django/template/__init__.py (revision 3077)
4+++ django/template/__init__.py (working copy)
5@@ -59,6 +59,7 @@
6 from django.utils.functional import curry
7 from django.conf import settings
8 from django.template.context import Context, RequestContext, ContextPopException
9+from django.core.exceptions import ObjectDoesNotExist
10 
11 __all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
12 
13@@ -626,37 +627,32 @@
14         current = context
15         bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR)
16         while bits:
17-            try: # dictionary lookup
18-                current = current[bits[0]]
19-            except (TypeError, AttributeError, KeyError):
20-                try: # attribute lookup
21-                    current = getattr(current, bits[0])
22-                    if callable(current):
23-                        if getattr(current, 'alters_data', False):
24-                            current = settings.TEMPLATE_STRING_IF_INVALID
25-                        else:
26-                            try: # method call (assuming no args required)
27-                                current = current()
28-                            except TypeError: # arguments *were* required
29-                                # GOTCHA: This will also catch any TypeError
30-                                # raised in the function itself.
31-                                current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call
32-                            except Exception, e:
33-                                if getattr(e, 'silent_variable_failure', False):
34-                                    current = settings.TEMPLATE_STRING_IF_INVALID
35-                                else:
36-                                    raise
37-                except (TypeError, AttributeError):
38-                    try: # list-index lookup
39-                        current = current[int(bits[0])]
40-                    except (IndexError, ValueError, KeyError):
41-                        raise VariableDoesNotExist, "Failed lookup for key [%s] in %r" % (bits[0], current) # missing attribute
42-                except Exception, e:
43-                    if getattr(e, 'silent_variable_failure', False):
44+            bit = bits.pop(0)
45+            if 'has_key' in dir(current) and current.has_key(bit): # dictionary lookup
46+                current = current[bit]
47+            elif bit in dir(current): # attribute lookup
48+                current = getattr(current, bit)
49+                if callable(current): # method call
50+                    if getattr(current, 'alters_data', False):
51                         current = settings.TEMPLATE_STRING_IF_INVALID
52                     else:
53-                        raise       
54-            del bits[0]
55+                        try:
56+                            current = current()
57+                        except TypeError: # arguments *were* required
58+                            current = settings.TEMPLATE_STRING_IF_INVALID # invalid method call
59+                        except Exception, e:
60+                            if getattr(e, 'silent_variable_failure', False):
61+                                current = settings.TEMPLATE_STRING_IF_INVALID
62+                            else:
63+                                raise
64+            elif type(current) == list or type(current) == tuple and bit.isdigit() and int(bit) < len(current):
65+                # list lookup
66+                current = current[int(bit)]
67+            else:
68+                if ObjectDoesNotExist.silent_variable_failure:
69+                    current = settings.TEMPLATE_STRING_IF_INVALID
70+                else:
71+                    raise VariableDoesNotExist, "Failed lookup for key [%s] in %r" % (bit, current) # missing attribute
72     return current
73 
74 class Node: