由于需要解决django template问题,研究了django template结构
一、django tempate 结构
django.tempate是django 模板的封装,主要由两部分构成:
- loader.py 总控入口
- loaders django自定义的一系列Loader,如django.template.loaders.filesystem.Loader
loader.py一些重要的类或者方法
def render_to_string(template_name, dictionary=None, context_instance=None) 入口 ,被shortcuts调用
def get_template(template_name) 被render_to_string调用 ,调用find_template
def find_template(name,dirs=None) 通过settings.TEMPLATE_LOADERS 加载template,被get_template调用
find_template_loader(loader) 通过className实例化loader,被 find_template调用,只要一个名叫load_template_source方法即可。
render_to_string()是template的入口:
def render_to_response(*args, **kwargs):
"""
Returns a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
httpresponse_kwargs = {'mimetype': kwargs.pop('mimetype', None)}
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
def render_to_string(template_name, dictionary=None, context_instance=None):
"""
Loads the given template_name and renders it with the given dictionary as
context. The template_name may be a string to load a single template using
get_template, or it may be a tuple to use select_template to find one of
the templates in the list. Returns a string.
"""
dictionary = dictionary or {}
if isinstance(template_name, (list, tuple)):
t = select_template(template_name)
else:
t = get_template(template_name)
if not context_instance:
return t.render(Context(dictionary))
# Add the dictionary to the context stack, ensuring it gets removed again
# to keep the context_instance in the same state it started in.
context_instance.update(dictionary)
try:
return t.render(context_instance)
finally:
context_instance.pop()
二、 django Template 的性能
django的Template性能非常差,就这么一段code, django 的template能跑10ms(而且blog.cached_tags is None)
{% if blog.cached_tags %}
{% if blog.is_buyable %}
{% for tag in blog.cached_tags %}
<a href="/blogs/item/{{ tag.name|urlencode }}/">
{{ tag.name }}
{% if user == sender or user.is_staff %}
<u title="删除标签"> </u>
{% endif %}
</a>
{% endfor %}
{% else %}
{% for tag in blog.cached_tags %}
<a href="/blogs/tag/{{ tag.name|urlencode }}/">
{{ tag.name }}
{% if user == sender or user.is_staff %}
<u title="删除标签"> </u>
{% endif %}
</a>
{% endfor %}
{% endif %}
{% else %}
{% if request.user != blog.sender and not request.user.is_staff %}
<b>还没有标签</b>
{% endif %}
{% endif %}
网上有一份python 各template的测试结果: