Fix a small typo in docs/upload_handling.txt
[django.git] / django / template / context.py
blob6ba53f340b2db58c8749baba3b9b5c04f8828c36
1 from django.conf import settings
2 from django.core.exceptions import ImproperlyConfigured
4 _standard_context_processors = None
6 class ContextPopException(Exception):
7 "pop() has been called more times than push()"
8 pass
10 class Context(object):
11 "A stack container for variable context"
12 def __init__(self, dict_=None, autoescape=True):
13 dict_ = dict_ or {}
14 self.dicts = [dict_]
15 self.autoescape = autoescape
17 def __repr__(self):
18 return repr(self.dicts)
20 def __iter__(self):
21 for d in self.dicts:
22 yield d
24 def push(self):
25 d = {}
26 self.dicts = [d] + self.dicts
27 return d
29 def pop(self):
30 if len(self.dicts) == 1:
31 raise ContextPopException
32 return self.dicts.pop(0)
34 def __setitem__(self, key, value):
35 "Set a variable in the current context"
36 self.dicts[0][key] = value
38 def __getitem__(self, key):
39 "Get a variable's value, starting at the current context and going upward"
40 for d in self.dicts:
41 if key in d:
42 return d[key]
43 raise KeyError(key)
45 def __delitem__(self, key):
46 "Delete a variable from the current context"
47 del self.dicts[0][key]
49 def has_key(self, key):
50 for d in self.dicts:
51 if key in d:
52 return True
53 return False
55 __contains__ = has_key
57 def get(self, key, otherwise=None):
58 for d in self.dicts:
59 if key in d:
60 return d[key]
61 return otherwise
63 def update(self, other_dict):
64 "Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
65 self.dicts = [other_dict] + self.dicts
66 return other_dict
68 # This is a function rather than module-level procedural code because we only
69 # want it to execute if somebody uses RequestContext.
70 def get_standard_processors():
71 global _standard_context_processors
72 if _standard_context_processors is None:
73 processors = []
74 for path in settings.TEMPLATE_CONTEXT_PROCESSORS:
75 i = path.rfind('.')
76 module, attr = path[:i], path[i+1:]
77 try:
78 mod = __import__(module, {}, {}, [attr])
79 except ImportError, e:
80 raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
81 try:
82 func = getattr(mod, attr)
83 except AttributeError:
84 raise ImproperlyConfigured('Module "%s" does not define a "%s" callable request processor' % (module, attr))
85 processors.append(func)
86 _standard_context_processors = tuple(processors)
87 return _standard_context_processors
89 class RequestContext(Context):
90 """
91 This subclass of template.Context automatically populates itself using
92 the processors defined in TEMPLATE_CONTEXT_PROCESSORS.
93 Additional processors can be specified as a list of callables
94 using the "processors" keyword argument.
95 """
96 def __init__(self, request, dict=None, processors=None):
97 Context.__init__(self, dict)
98 if processors is None:
99 processors = ()
100 else:
101 processors = tuple(processors)
102 for processor in get_standard_processors() + processors:
103 self.update(processor(request))