[Dynamic Language] Python Django: 模板引擎(4)在视图中使用模板和模板继承

Django 视图中使用模板

模板加载
首先设置 setting.py 文件的 TEMPLATE_DIRS ,告诉Django框架我们的模板文件存放的位置。

TEMPLATE_DIRS = (
'/home/django_test/mysite/templates', //模板存放目录
)

import os.path
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),
)

我们先看一个视图中使用模板的简单示例
在路由代码添加test路径

代码
1 from django.conf.urls.defaults import *
2 from mysite.views import *

7 urlpatterns = patterns(
8 '',
9 ('^$', index),
10 ('^hello/$',hello),
11 ('^time$', current_datetime),
12 ('^test$',test), // 添加test路径
13 )

视图代码调用test.html模板

代码
1 from django.template.loader import get_template
2 from django.template import Template, Context
3 from django.http import HttpResponse

18 def test(request):
19 name = "abeen"
20 t = get_template('test.html') // 加载test.html模板
21 html = t.render(Context({'name': name}))
22 return HttpResponse(html);

模板代码

<html>
<body>
Hello {{ name }}.
</body>
</html>

运行显示结果
Hello abeen.

Django在视图中使用模板就这么简单。

---------------------------------------------------------------------------------------------------------------

HttpResponser
还可以使用 django.shortcuts 模块中的 render_to_response() 函数,一次性载入、渲染并作为HttpResponser返回。

1 from django.template.loader import get_template
3 from django.http import HttpResponse

18 def test(request):
19 name = "abeen"
20 return render_to_response('test.html',{'name': name})

locals()
也可以使用Python 的内建函数 locals() ,它返回的字典对所有局部变量的名称与值进行映射。
视图可以修改为

代码
1 from django.shortcuts import render_to_response
3 from django.http import HttpResponse
4 import datetime

18 def test(request):
19 name = "abeen"
20 return render_to_response('test.html',locals())

使用模板子目录

t = get_template('theme1/test.html')
return render_to_response('theme1/test.html',locals())

使用 include 模板标签,在模板中包含其它模板的内容

{% include 'test.html' %}
{
% include 'theme1/test.html' %} //子目录模板
{
% include template_name %} //以变量 template_name 的值为名称的模板内容

mypage.html模板中包含includes/nav.html模板

# mypage.html
<html>
<body>
{% include "includes/nav.html" %}
<h1>{{ title }}</h1>
</body>
</html>

# includes/nav.html

<div id="nav">
You are in: {{ current_section }}
</div>


模板继承
Django的模板可以继承,在基模板中使用多个{% block %}模板标签,此模板标签告诉子模板可以重载这些部分,
每个{% block %}要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

创建基础模板

代码
# base.html
1
<html>
2
<head>
3
<title> {% block title%}{% endblock %} </title>
4
</head>
5
<body>
6 {% block head %}
7
<div style="background:Gray"> this the head </div>
8 {% endblock %}
9
10 {% block content %}{% endblock %}
11
12 {% block foot%}
13
<div style="background:Gray"> this the foot </div>
14 {% endblock %}
15
16
</body>
17
</html>

子模板一

1 {% extends "theme1/base.html"%}
2
3 {% block title %} show current time {% endblock %}
4
5 {% block content %}
6 It is now {{ current_date }}.
7 {% endblock %}

子模板二

代码
1 {% extends "theme1/base.html"%}
2
3 {% block title %} test template used {% endblock %}
4
5 {% block content%}
6
7 {% ifequal name name %}
8
<p> welcome {{ name|upper }} and {{ name1|lower|upper }}</p>
9 {% else %}
10
<p> the name != name1 </p>
11 {% endifequal %}
12
13 {% comment %}
14
<ul>
15 {% if namelist %}
16 {% for name in namelist %}
17
<li> {{ name }} </li>
18 {% for subname in name %}
19
<li>{{ subname }}</li>
20 {% endfor %}
21 {% endfor %}
22 {% else %}
23 the namelist is empty.
24 {% endif %}
25
</ul>
26 {% endcomment %}
27
28
<ul>
29 {% for name in namelist %}
30 {% if forloop.first %}
31 this first name is : {{ name }}
</br>
32 {% endif %}
33 {{ forloop.counter }} : {{ name }}
34
35 {% for subname in name %}
36
<li>{{ subname }}</li>
37 {% endfor %}
38
39 {% if forloop.last %}
40 this last name is : {{ name }}
</br>
41 {% endif %}
42 {% empty %}
43 the namelist is empty.
44 {% endfor %}
45
</ul>
46
47 {% endblock %}

在加载子模板时,模板引擎发现 {% extends  %} 标签, 注意到该模板是一个子模板。模板引擎立即装载其父模板。此时,模板引擎注意到父模板中的 {% block %}  标签,并用子模板的内容替换这些 block 。子模板中没有定义的块,模板系统将使用在父模板中定义的值。 父模板 {% block  %} 标签中的内容总是被当作一条退路。继承并不会影响到模板的上下文。 换句话说,任何处在继承树上的模板都可以访问到你传到模板中的每一个模板变量。


以下是使用模板继承的一些诀窍:
 1、如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。


 2、一般来说,基础模板中的 {% block %} 标签越多越好。记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。


 3、如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。


 4、如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。


 5、不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block 标签的工作方式是双向的。 也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。


 6、{% extends %} 对所传入模板名称使用的加载方法和 get_template() 相同。 也就是说,会将模板名称被添加到 TEMPLATE_DIRS 设置之后。


 7、多数情况下, {% extends %} 的参数应该是字符串,但是如果直到运行时方能确定父模板名,这个参数也可以是个变量。 这使得你能够实现一些很酷的动态功能。

原文地址:https://www.cnblogs.com/abeen/p/1763048.html