警惕Context的push()和pop()
遇到一个怪异的bug是在自己实现的一个可能存在嵌套的templatetags里,下面这行代码带入的templatecontext这个dict会被update到context_instance里面去,并且可能是同名的。
output = render_to_string(templatepath, templatecontext, context_instance)
看了django的文档其中Context上有 push()和pop(), 所以想当然地认为只要在调用前对context_instance 执行push(), 结束了pop()就可以保证templatecontext里的东西不会被混入context_instance里面去。
实际的情况却不是我所期待的,常常会出现context里的对象被替换了(由于是嵌套的,所以必然存在重名)。郁闷之下只好去看看push(), pop(),还有render_to_string()究竟在干什么。
原来这push(), pop()是这么实现的:
27 def push(self):
28 d = {}
29 self.dicts.append(d)
30 return d
31
32 def pop(self):
33 if len(self.dicts) == 1:
34 raise ContextPopException
35 return self.dicts.pop()
Render_to_string()是这样的:
157 def render_to_string(template_name, dictionary=None, context_instance=None):
158 """
159 Loads the given template_name and renders it with the given dictionary as
160 context. The template_name may be a string to load a single template using
161 get_template, or it may be a tuple to use select_template to find one of
162 the templates in the list. Returns a string.
163 """
164 dictionary = dictionary or {}
165 if isinstance(template_name, (list, tuple)):
166 t = select_template(template_name)
167 else:
168 t = get_template(template_name)
169 if context_instance:
170 context_instance.update(dictionary)
171 else:
172 context_instance = Context(dictionary)
173 return t.render(context_instance)
这里用到的context.update()是这样实现的
75 def update(self, other_dict):
76 "Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
77 if not hasattr(other_dict, '__getitem__'):
78 raise TypeError('other_dict must be a mapping (dictionary-like) object.')
79 self.dicts.append(other_dict)
80 return other_dict
由此可见,我在调用Render_to_string()前push(), 后pop()根本不能达到我要的目的,事实上那个pop只是pop出update()进去的dictionary.
解决方案是,不需要push(), 每次render_to_string()后调用pop(), context_instance就复原了。
Related posts:
- Looking for partners to attend Startup Weekend Seattle in Mar 19-21
- app-engine-patch is now officially dead
- 警惕Context的push()和pop()
- GAE的blobstore初步体验
- Seattle: 开放P2P云计算平台 / 未来的anti GFW利器?
- Northwest Python Day 2010
- App Engine Patch对支持Generic View的一个问题和解决方案
- Reusable webapp的思考(5)
- python module path含有. 的问题
- Webapp level context processors
Search related in web: