您的位置:首页 > 编程语言 > Go语言

第四章 Django模板系统

2013-05-30 17:31 260 查看
第四章 Django模板系统
1、模板系统基本知识
Django 模板是用于分割文档的表示和数据的字符串文本
例子:
<html>
<head><title>Ordering notice</title></head>

<body>

<h1>Ordering notice</h1>

<p>Dear {{ person_name }},</p>     #用两个大括号括起来的文字(例如 {{ person_name }} )称为 变量

<p>Thanks for placing an order from {{ company }}. It's scheduled to
ship on {{ ship_date|date:"F j, Y" }}.</p>     #将变量ship_date传递给date过滤器,同时指定参数”F j,Y”。date过滤器根据参数进行格式输出

<p>Here are the items you've ordered:</p>

<ul>
{% for item in item_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>

{% if ordered_warranty %}     #被大括号和百分号包围的文本(例如 {% if ordered_warranty %})是 模板标签
<p>Your warranty information will be included in the packaging.</p>
{% else %}
<p>You didn't order a warranty, so you're on your own when
the products inevitably stop working.</p>
{% endif %}

<p>Sincerely,<br />{{ company }}</p>

</body>
</html>


2、如何使用模板系统
1)创建模板对象
写模板,创建 Template对象,创建 Context,调用 render()方法
①可以用原始的模板代码字符串创建一个 Template对象, 或用指定模板文件路径的方式创建来 Template对象
②调用 Template对象的 render()方法并提供给他变量,返回一个完整的模板字符串内容,包含了所有标签块与变量解析后的内容
2)模板渲染
创建一个 Template对象,你可以用 context来传递数据给它
一个context是一个字典映射变量和它们的值。模板使用它来赋值模板变量标签和执行块标签
>>> from django.template import Context, Template
>>> t = Template('My name is {{ name }}.')
>>> c = Context({'name': 'Stephane'})
>>> t.render(c)
u'My name is Stephane.'

注:使用了三个引号来 标识这些文本,因为这样可以包含多行
3)字典和Contexts
字典数据类型就是关键字和它们值的一个映射。 Context和字典很类似
4)同一模板,多个上下文
一旦有了 模板对象,你就可以通过它渲染多个背景(context)
只创建 一次 模板对象,然后对它多次调用 render()将会更加高效
5)深度变量的查找
使用句点可以访问list、dictionary和自定义的对象
>>> from django.template import Template, Context
>>> class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
u'Hello, John Smith.'

句点查找规则可概括为: 当模板系统在变量名中遇到点时,按照以下顺序尝试进行查找:

①字典类型查找 (比如 foo["bar"] )1
②属性查找 (比如 foo.bar )
③方法调用 (比如 foo.bar() )
④列表类型索引查找 (比如 foo[bar] )

系统使用找到的第一个有效类型。 这是一种短路逻辑
句点查找可以多级深度嵌套。 例如在下面这个例子中 {{person.name.upper}} 会转换成字典类型查找( person['name'] ) 然后是方法调用( upper() )
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name.upper }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
u'SALLY is 43 years old.'

6)如何处理无效变量
默认情况下,如果一个变量不存在,模板系统会把它展示为空字符串
7)玩一玩上下文(context)对象
>>> from django.template import Context
>>> c = Context({"foo": "bar"})
>>> c['foo']
'bar'
>>> del c['foo']


3、基本的模板标签和过滤器
1)标签if/else/endif
①合法组合
{% if %}{% else %} {% endif %}
注:一定要用 {% endif %} 关闭每一个 {% if %} 标签

②Python 的“真值”
python中空的列表 ([]),tuple(()),字典({}),字符串(''),零(0),还有None对象,在逻辑判断中都为假,其他的情况都为真

③规则
{% if %}标签接受 and , or 或者 not 关键字来对多个变量做判断 ,或者对变量取反( not )
{% if %}不允许在同一个标签中同时使用 and 和 or
系统不支持用圆括号来组合比较操作,考虑用嵌套的{% if %}标签替换

2)标签for
①合法组合
{% for %} {% endfor %}
循环语法是 for X in Y,Y是要迭代的序列而X是在每一个特定的循环中使用的变量名称
②语法
reversed使得该列表被反向迭代
可以嵌套使用 {% for %}标签,一定要有{% endfor %}关闭每一个{% for %}
Django不支持退出循环操作,也不支持continue语句
forloop.counter总是一个表示当前循环的执行次数的整数计数器
forloop.counter0类似于 forloop.counter,但是它是从0计数的
forloop.revcounter是表示循环中剩余项的整型变量
forloop.revcounter0类似于 forloop.revcounter,但它以0做为结束索引
forloop.first是一个布尔值,在第一次执行循环时该变量为True(例:菜单)
forloop.last是一个布尔值,在最后一次执行循环时被置为True(例:管道符号)
forloop.parentloop是一个指向当前循环的上一级循环的 forloop对象的引用(在嵌套循环的情况下)

3)标签ifequal/ifnotequal
①合法组合
{% ifequal %} {% endifequal %}
支持可选的 {% else%}标签
②语法
只有模板变量,字符串,整数和小数可以作为 {% ifequal %}标签的参数
其他的一些类型,例如Python的字典类型、列表类型、布尔类型,不能用在 {% ifequal %}中

4)注释
注释使用 {# #},不能跨行
例:{# This is a comment #}

5)过滤器
①模板过滤器是在变量被显示前修改它的值的一个简单方法
例:{{ name|lower }}
显示的内容是变量 {{ name }}被过滤器 lower处理后的结果,它功能是转换文本为小写

②有些过滤器有参数。过滤器参数看起来是这样的: 
{{ bio|truncatewords:"30" }}

显示变量 bio的前30个词。过滤器参数总是使用双引号标识

4、在视图中使用模板
1)模板加载
将模板的保存位置告诉框架
配置文件:settings.py
TEMPLATE_DIRS设置,告诉 Django 的模板加载机制在哪里查找模板
例:
TEMPLATE_DIRS = (
'/home/django/mysite/templates',
)

注:不要忘记模板目录字符串尾部的逗号!Python 要求单元素元组中必须使用逗号,以此消除与圆括号表达式之间的歧义
如果 TEMPLATE_DIRS包含多个目录,它将会查找每个目录直至找到模板或找遍所有目录
import os.path
TEMPLATE_DIRS = (
os.path.join(os.path.dirname(__file__), 'templates').replace('\\','/'),      #内部变量 __file__,该变量被自动设置为代码所在的 Python 模块文件名
)


2)render_to_response()
django.shortcuts模块中名为 render_to_response()的函数
功能:加载模板、填充 context、将经解析的模板结果返回为 HttpResponse对象
视图current_datetime:
from django.shortcuts import render_to_response
import datetime

def current_datetime(request):
now = datetime.datetime.now()
return render_to_response('current_datetime.html', {'current_date': now})     #第一个参数模板名称,第二个参数字典


3)locals() 技巧
包括所有的局部变量
def current_datetime(request):
current_date = datetime.datetime.now()
return render_to_response('current_datetime.html', locals()


4)get_template()中使用子目录
只需在调用 get_template()时,把子目录名和一条斜杠添加到模板名称之前

如: 
t = get_template('dateapp/current_datetime.html')


5)include模板标签
{% include %},该标签允许在(模板中)包含其它的模板的内容
标签的参数是所要包含的模板名称,可以是一个变量,也可以是用单/双引号硬编码的字符串

6)模板继承
1)模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载
①定义base.html模板,该框架之后将由 子模板所继承
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>     #{% block %}标签告诉模板引擎,子模板可以重载这些部分
</head>
<body>
<h1>My helpful timestamp site</h1>
{% block content %}{% endblock %}
{% block footer %}
<hr>
<p>Thanks for visiting my site.</p>
{% endblock %}
</body>
</html>

②修改 current_datetime.html模板来使用基本模板
{% extends "base.html" %}     #{% extends %}标签,装载其父模板

{% block title %}The current time{% endblock %}

{% block content %}
<p>It is now {{ current_date }}.</p>
{% endblock %}

2)注意:
①{% extends %},必须保证其为模板中的第一个模板标记。否则,模板继承将不起作用
②一般来说,基础模板中的 {% block %}标签越多越好
③如果需要获得父模板中代码块的内容,可以使用 {{ block.super }}变量
④{% extends %}对所传入模板名称使用的加载方法和 get_template()相同
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Django 标签