模板简介
模板就是一个文件,格式可以是:HTML,XML,CSV,etc
一个模板包好变量(在模板求值时用值替换)和标记(模板加载时的逻辑控制)
{% extends "base_generic.html" %} # 母版
{% block title %}{{ section.title }}{% endblock %} # 块标记,重载母版的此模块内容
{% block content %}
<h1>{{ section.title }}</h1>
{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}"> # 变量
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p> # 标记,截断字符串
{% endfor %}
{% endblock %}
模板渲染
模板变量
变量表现为{{ variable }},在加载时它将替换成对应值。
变量名由字母数字字符和下划线(“_”)的任何组合组成,但不能以下划线开头。点(".")也出现在变量部分,尽管它有一个特殊的含义,如下所示。重要的是,变量名中不能有空格或标点字符。
点(".")查找顺序
- 字典(dictionary)查找
- 属性(attribute)或者方法(method)查找
- 索引查找
注:只有没有参数的简单方法才能在模板中调用
例子:
{% for k, v in defaultdict.items %}
Do something with k and v here...
{% endfor %}
过滤器
在模板中可以使用过滤器进行逻辑惭怍
标签
在模板中可以使用标签进行逻辑操作
注释
在模板中使用{# #}进行注释
{# greeting #}hello
模板继承
Django模板引擎中最强大的部分(因此也是最复杂的部分)是模板继承。模板继承允许您构建一个基本的“骨架”模板,该模板包含站点的所有公共元素,并定义子模板可以覆盖的block。
the base.html
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
the children html
{% extends "base.html" %} # 加载母版
{% block title %}My amazing blog{% endblock %} # 重载母版
{% block content %} # 重载母版
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
说明:
- extends标签告诉当前模板是由其他模板继承而来。当模板进行求值时,首先加载这个父模板(base.html)。
- 如果子模板没有重载父模板中的{% block %}标签,父模板中的内容将被加载到当前内容里。
模板继承实现了代码重用,并更易维护。
模板继承使用技巧
- 如果在模板中使用{% extends %},那么它必须是该模板中的第一个模板标记。否则,模板继承将无法工作。
- 基础模板中有更多的{% block %}标记更好。记住,子模板不必定义所有的父模块,因此您可以在一些模块中填写合理的默认值,然后只定义您稍后需要的。挂钩越多越好。
- 如果您发现自己在多个模板中复制了内容,这可能意味着您应该将该内容移动到父模板中的{% block %}。
- 如果需要从父模板({{block)中获取块的{{block.super}}变量可以做到这一点。如果您想要添加到父块的内容而不是完全覆盖它,那么这是非常有用的。使用{{block.super}}不会自动转义(请参阅下一节),因为如果需要,它已经在父模板中转义了。
- 使用模板标记在{% block %}之外创建的变量不能在块内使用。
注:模板的 block可以命名,但是不可以在同一模板中定义相同名字的 block。
其他知识点
自动转义
为防止可能存在在xxs攻击,模板会将html和javascript标签自动转义。
如果可以确定内容是安全的,并且需要正确显示它,可以使用safe过滤器
This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
对于一整个块想取消转义,可以使用autoescape标签
{% autoescape off %}
Hello {{ name }}
{% endautoescape %}
autoescape标签可以嵌套,来控制哪些内容需要转义,哪些内容不需要转义
Auto-escaping is on by default. Hello {{ name }}
{% autoescape off %}
This will not be auto-escaped: {{ data }}.
Nor this: {{ other_data }}
{% autoescape on %}
Auto-escaping applies again: {{ name }}
{% endautoescape %}
{% endautoescape %}
注:autoescape将传递效果给extend和include标签。
default后的内容不会被转义,应该手动写成转义字符替代原内容
{{ data|default:"3 < 2" }}
{{ data|default:"3 < 2" }} {# Bad! Don't do this. #}
调用方法
方法必须的无参数方法
{{ task.comment_set.all.count }} # 调用时不加()
自定义标签和过滤器
需要注册app到settings.py的INSTALLED_APPS中
并且将用自定义标签和过滤器加载到调用的模板中 {% load mytags %}