1 模板渲染过程

模板处理分为两个过程:

  • 加载模板
  • 渲染模板

查看源码:

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """ Returns a HttpResponse whose content is filled with the result of calling django.template.loader.render_to_string() with the passed arguments. """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

def render_to_string(template_name, context=None, request=None, using=None):
    """ Loads a template and renders it with a context. Returns a string. template_name may be a string or a list of strings. """
    if isinstance(template_name, (list, tuple)):
        template = select_template(template_name, using=using)
    else:
        template = get_template(template_name, using=using)		# 关键
    return template.render(context, request)					# 关键

所以我们可以转化为:

def hellotemplate(request):

    #return render(request,'HelloTemplate.html')

    template = loader.get_template('HelloTemplate.html')		# 1.加载模板
    content = template.render()									# 2.渲染模板

    return HttpResponse(content)

2 模板组成

模板主要有两部分组成:

  • HTML静态代码
  • 动态插入的代码段(挖坑、填坑
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>StudentList</title>
</head>
<body>

<ul>
    {% for student in students %}
        <li>{{student.s_name}}</li>			# 挖坑
    {% endfor %}
</ul>
</body>
</html>

模板中的动态代码段除了做基本的静态填充,还可以实现一些基本的运算、转换和逻辑

模板中的变量:

  • 视图传递给模板的数据
  • 遵循标识符规则
  • 语法{{var}}
  • 如果变量不存在,则插入空字符串

3 模板语法

3.1 点语法

模板中的点语法可以有三种用途:

  • 字典查询,充当字典中的key
  • 属性或者方法
  • 索引

模板中的小弊端,调用对象的方法不能传参

演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Employees</title>
</head>
<body>

员工列表:
<ul>

    {% for employee in employees %}
    <li>{{ employee.e_name }}</li>			# 访问属性
    {% endfor %}

</ul>
---------------------
<br>
{{ employees.0.e_name }}						# 访问索引

</body>
</html>

输出:

3.2 模板标签(控制语句)

if/else 标签

基本语法格式如下:

{% if condition %}
     ... display
{% endif %}

或者

{% if condition %}
     ... display1
{% else %}
	 ... display2
{% endif %}

或者

{% if condition1 %}
   ... display 1
{% elif condition2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

for 标签

{% for %} 允许我们在一个序列上迭代。
与Python的 for 语句的情形类似,循环语法是 for X in Y ,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称。
每一次循环中,模板系统会渲染在 {% for %} 和 {% endfor %} 之间的所有内容。

<ul>
{% for 变量 in 列表 %}
    语句1
    {% empty %}
    语句2
{% endfor %}
</ul>

当列表为空或者不存在时,执行empty之后的语句。

forloop标签

{{forloop.count}} 表示当前第几次循环,从1开始
{{forloop.count0}} 表示当前第几次循环,从0开始
{{forloop.revcount}} 表示当前第几次循环,倒着数数,到1结束
{{forloop.revcount0}} 表示当前第几次循环,倒着数数,到0结束
{{forloop.first}} 是否是第一个 Bool
{{forloop.last}} 是否是最后一个 Bool

注释标签

Django 单行注释使用 {# #}。

{# 这是一个注释 #}

Django 多行注释使用 {% comment %}。

{% comment %}
内容
{% endcomment %}

过滤器

模板过滤器可以在变量被显示前修改它,过滤器使用管道字符,如下所示:

{{var | 过滤器}}

过滤器的种类:

add		{{p.page|add:5}}			+5
add		{{p.page|add:-5}}			-5
upper	{{student.name|upper}}		大写
lower	{{student.name|lower}}		小写

过滤器可以传递参数,参数使用引号引起来:

比如:join	{{students|join '='}}

根据指定格式转换日期为时间字符串
{{dateVal|date:'y-m-d'}}

过滤管道可以被套接,既是说,一个过滤器管道的输出又可以作为下一个管道的输入:

{{ my_list|first|upper }}

include标签
{% include %} 标签允许在模板中包含其它的模板的内容。

缺点:效率不如block+extends高。

编写add.html

<p>我来自另一个html文件的内容</p>

在另一个html添加,并访问

{% include 'add.html' %}

效果如下:

4 模板继承

模板可以用继承的方式来实现复用。

4.1 用例

接下来我们先创建之前项目的 templates 目录中添加 base.html 文件,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>电商站点</title>
</head>
<body>
<p>我是一个基本网页框架</p>

{% block header %}
{% endblock %}

{% block banner %}
{% endblock %}

{% block content %}
{% endblock %}

{% block footer %}
{% endblock %}

</body>
</html>

编写home.html:

{% extends 'base.html' %}

{% block banner %}
    <p>我是一个banner</p>
{% endblock %}

{% block content %}
    <p>我是正文!</p>
{% endblock %}

添加路由、视图函数,并访问

urlpatterns=[
    url(r'^home/', views.home),
]


def home(request):
    return render(request,'home.html')

效果展示:

4.2 结构标签

block

  • 用来规划我们的布局(挖坑
  • 首次出现代表规划
  • 第二次出现代表填充以前的规划
  • 第三次出现代表填充以前的规划,默认动作是覆盖(重写
    • 如果不想覆盖,请填写{{block.super}}
    • 这样就实现了增量式操作

用例
编写home2.html

{% extends 'home.html' %}

{% block banner %}		# 第三次出现,默认重写
    <p>我是被重写过的banner</p>
{% endblock %}

{% block content %}
    {{ block.super }}	# 增量语句
    <p>我是增量后的正文!</p>
{% endblock %}

效果如下:

extends

  • 继承
  • 可以获取父模板中的所有结构