django 0.96 与 django 1.2 之间的细微差别造成很多麻烦事。
一、自动转换(autoescape)的问题
autoescape 主要是为了防止模板变量中含有标签等html元素,它会自动将html标签等元素转换实体。
例如:把
<script>
转换成
<script>
但是 django 0.96 没有autoescape,而django 1.2默认会自动对模板变量进行过滤。从0.96更换至1.2的时候,会发现很多不想被过滤的标签全都被过滤了,可以使用safe标记成安全字符。
如果使用了escape过滤器,则不管它出现在过滤链条的哪个位置,一律只会在链条的最后执行。并且如果变量已经标记为safe,那么escape则不会做任何事情。
例如:
{{ val|safe }}
解决办法有两种,一种是将原来模板中的escape去掉,再把不需要过滤的挨个修改成safe。另一种就是全局关闭autoescape:
{% autoescape off %}
....模板其他部分...
{% endautoescape %}
二、{% spaceless %}标签默认行为差别
在 django 0.96 中,去掉所有标签间的空白符号,仅标签间留一个空格。
在 django 1.2 中,去掉所有标签间的空白符号,标签间什么都不留。
举例:
<a href="#">This</a> <a href="#">is</a> <a href="#">mine</a>.
django 0.96 显示为:
This is mine.
django 1.2 显示成:
Thisismine.
这个解决办法很简单,不用这个标签即可,用与不用一般没什么区别。
三、{% include %}与{% base %}标签的路径问题
django 1.2 的标签中,不能使用上层路径,只能从模板根目录向下找。
在 django 0.96 中,可以这样使用:
{% include "../home.html" %}
而在 django 1.2 你必须这样:
{% include "path/to/home.html" %}
对比一下0.96与1.2的 django.template.loaders.file_system 模块,就会发现 get_template_sources 方法的文件路径结合方式不同。0.96 用的是一般的 os.path.join 方法,而 1.2 用的是 django.utils._os.safe_join 方法,后者限制不允许使用 base path 外的路径。而 include 和 extends 标签会先从base path开始寻找模板(这也许是bug?),如果路径里边有 “../” 可能会直接跳出这个 base path ,于是会触发异常:
>>> from django.utils._os import safe_join
>>> safe_join('templates','../bbb.html')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python26\lib\site-packages\django\utils\_os.py", line 44, in safe_joi
n
raise ValueError('the joined path is located outside of the base path'
ValueError: the joined path is located outside of the base path component
>>>
另外一个麻烦事就是在django 1.2中必须使用一个空app进行初始化设置才能正确找到模板。
举例,
目录结构:
project
|--templates
| |--outter.html
| |--bbb
| | |--in_b.html
| |--aaa
| | |--in_a.html
outter.html :
{% include "bbb/in_b.html"%}
in_a.html :
{% include "bbb/in_b.html"%}
main.py:
from google.appengine.dist import use_library
use_library('django', '1.2')
from django.conf import settings
#必须找个空文件(nothing.py)作为引子才能正确找到模板文件
settings.configure(INSTALLED_APPS=('nothing',))
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util, template
import os
class MainHandler(webapp.RequestHandler):
def get(self):
#不论settings是否设置INSTALLED_APPS=('nothing',)
#在outter.html中总能找到bbb/in_b.html或aaa/in_b.html
self.render('outter.html', debug=True)
#在aaa/in_a.html中,只有在settings中设置了
#INSTALLED_APPS=('nothing',)时
#才能正确找到 bbb/in_b.html ,反过来也是一样。
self.render('aaa/in_a.html', debug=True)
def render(self, tpl, vals={},debug=False):
directory=os.path.dirname(__file__)
path=os.path.join(directory, os.path.join('templates',tpl))
self.response.out.write(template.render(path, vals, debug))
def main():
application = webapp.WSGIApplication([('/', MainHandler)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
参考:
1、https://groups.google.com/forum/#!msg/google-appengine-python/YaqfeygoiaI/RtDh9pL6XJQJ
More