关于方法调用
方法调用要比其他的查询稍微复杂一点,下面是需要记住的几点: 1,在方法查询的时候,如果一个方法触发了异常,这个异常会传递从而导致渲染失 败,但是如果异常有一个值为True的silent_variable_failure属性,这个变量会渲染成空string:- >>> t = Template("My name is { { person.first_name }}.")
- >>> class PersonClas3:
- ... def first_name(self):
- ... raise AssertionError, "foo"
- >>> p = PersonClass3()
- >>> t.render(Context({ "person": p}))
- Traceback (most recent call last):
- ...
- AssertionError: foo
- >>> class SilentAssetionError(AssertionError):
- ... silent_variable_failure = True
- >>> class PersonClass4:
- ... def first_name(self):
- ... raise SilentAssertionError
- >>> p = PersonClass4()
- >>> t.render(Context({ "person": p}))
- "My name is ."
- def delete(self):
- # Delete the account
- delete.alters_data = True
不合法的变量怎样处理
默认情况下如果变量不存在,模板系统会把它渲染成空string,例如:- >>> from django.template import Template, Context
- >>> t = Template('Your name is { { name }}.')
- >>> t.render(Context())
- 'Your name is .'
- >>> t.render(Context({'var': 'hello'}))
- 'Your name is .'
- >>> t.render(Context({'NAME': 'hello'}))
- 'Your name is .'
- >>> t.render(Context({'Name': 'hello'}))
- 'Your name is .'
玩玩Context对象
大多数情况下你初始化Context对象会传递一个字典给Context() 一旦你初始化了Context,你可以使用标准Python字典语法增减Context对象的items:- >>> from django.template import Context
- >>> c = Context({ "foo": "bar"})
- >>> c['foo']
- 'bar'
- >>> del c['foo']
- >>> c['foo']
- ''
- >>> c['newvariable'] = 'hello'
- >>> c['newvariable']
- 'hello'
- >>> c = Context()
- >>> c['foo'] = 'first level'
- >>> c.push()
- >>> c['foo'] = 'second level'
- >>> c['foo']
- 'second level'
- >>> c.pop()
- >>> c['foo']
- 'first level'
- >>> c['foo'] = 'overwritten'
- >>> c['foo']
- 'overwritten'
- >>> c.pop()
- Traceback (most recent call last):
- ...
- django.template.ContextPopException
模板标签和过滤器基础
我们已经提到模板系统使用内建的标签和过滤器 这里我们看看常见的,附录6包含了完整的内建标签和过滤器,你自己熟悉那个列表来了解可以做什么是个好主意if/else
{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值 系统则会显示{% if %}和{% endif %}间的所有内容:- {% if today_is_weekend %}
- <p>Welcome to the weekend!</p>
- {% else %}
- <p>Get back to work.</p>
- {% endif %}
- {% if athlete_list and coach_list %}
- Both athletes and coaches are available.
- {% endif %}
- {% if not athlete_list %}
- There are no athletes.
- {% endif %}
- {% if athlete_list or coach_list %}
- There are some athletes or some coaches.
- {% endif %}
- {% if not athlete_list or coach_list %}
- There are no athletes or there are some coaches.
- {% endif %}
- {% if athlete_list and not coach_list %}
- There are some athletes and absolutely no coaches.
- {% endif %}
- {% if athlete_list and coach_list or cheerleader_list %}
- {% if athlete_list %}
- {% if coach_list or cheerleader_list %}
- We have athletes, and either coaches or cheerleaders!
- {% endif %}
- {% endif %}
- {% if athlete_list or coach_list or parent_list or teacher_list %}
- {% if athlete_list %}
- <p>Here are the athletes: { { athlete_list }}.</p>
- {% else %}
- <p>No athletes are available.</p>
- {% if coach_list %}
- <p>Here are the coaches: { { coach_list }}.</p>
- {% endif %}
- {% endif %}
for
{% for %}标签允许你按顺序遍历一个序列中的各个元素 Python的for语句语法为for X in Y,X是用来遍历Y的变量 每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容 例如,显示给定athlete_list变量来显示athlete列表:- <ul>
- {% for athlete in athlete_list %}
- <li>{ { athlete.name }}</li>
- {% endfor %}
- </ul>
- {% for athlete in athlete_list reversed %}
- ...
- {% endfor %}
- {% for %}标签可以嵌套:
- {% for country in countries %}
- <h1>{ { country.name }}</h1>
- <ul>
- {% for city in country.city_list %}
- <li>{ { city }}</li>
- {% endfor %}
- </ul>
- {% endfor %}
- {% for item in todo_list %}
- <p>{ { forloop.counter }}: { { item }}</p>
- {% endfor %}
- {% for object in objects %}
- {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
- { { object }}
- </li>
- {% endfor %}
- {% for link in links %}{ { link }}{% if not forloop.last %} | {% endif %}{% endfor %}
- {% for country in countries %}
- <table>
- {% for city in country.city_list %}
- <tr>
- <td>Country #{ { forloop.parentloop.counter }} </td>
- <td>City #{ { forloop.counter }}</td>
- <td>{ { city }}</td>
- </tr>
- {% endfor %}
- </table>
- {% endfor %}
ifequal/ifnotequal
Django模板系统并不是一个严格意义上的编程语言,所以它并不允许我们执行Python语句 (我们会在‘哲学和限制‘一节详细讨论)。 然而在模板语言里比较两个值并且在他们一致的时候显示一些内容,确实是一个在常见不过的需求了——所以Django提供了ifequal标签。 {% ifequal %}比较两个值,如果相等,则显示{% ifequal %}和{% endifequal %}之间的所有内容:- {% ifequal user currentuser %}
- <h1>Welcome!</h1>
- {% endifequal %}
- {% ifequal section 'sitenews' %}
- <h1>Site News</h1>
- {% endifequal %}
- {% ifequal section "community" %}
- <h1>Community</h1>
- {% endifequal %}
- {% ifequal section 'sitenews' %}
- <h1>Site News</h1>
- {% else %}
- <h1>No News Here</h1>
- {% endifequal %}
- {% ifequal variable 1 %}
- {% ifequal variable 1.23 %}
- {% ifequal variable 'foo' %}
- {% ifequal variable "foo" %}
- {% ifequal variable True %}
- {% ifequal variable [1, 2, 3,]%}
- {% ifequal variable {'key': 'value'} %
注释
和HTML或编程语言如Python一样,Django模板语言允许注释{# #},如:- {# This is a comment #}
过滤器
本章前面提到,模板过滤器是变量显示前转换它们的值的方式,看起来像下面这样:- { { name|lower }}
- { { my_text|escape|linebreaks }}
- { { bio|truncatewords:"30" }}
- { { pub_date|date:"F j, Y" }}
- Converts & to &
- Converts < to <
- Converts > to >
- Converts "(双引号) to "
- Converts '(单引号) to '
变量
变量的形式:{ { variable }}
使用句点 “.” 可以访问变量的属性.
例如{ { section.title }} 会被 section 对象的 title 属性替换.
如果你用到的变量不存在,模板系统会插入一个值:TEMPLATE_STRING_IF_INVALID ,这个值在settings中定义, 默认是一个空字符串.
过滤器
可以定制变量的显示格式。
{ { name|lower }}. 这将显示 { { name }} 变量通过 lower 过滤后的值. 它将文本转换为小写.
{ { text|escape|linebreaks }} 用于将文本内容转义然后将换行转换成 <p> 标签.
标签
{% 标签 %}
有些标签要求有开始标记和结束标记,例如: {% block title %}My amazing site{% endblock %}
模板继承
模板继承允许你建立一个基本的”骨架”模板, 它包含你所有最常用的站点元素 并 定义了一些可以被子模板覆盖的block.
{% block title %}久久寻网{% endblock %} {% block content %}{% endblock %}
我们称它为 base.html, 定义了一些简单的 HTML 骨架文档, 你可以把它用到一些简单两列的网页上. “子” 模板的任务就是用内容填写这些空白的内容块.
子模板
如果你在模板中使用了 “{% extends %}“ ,那么它必须是这个模板中的第一个模板 tag ,否则它就不工作
如果你需要在子模板中引用父模板中的 block 的内容,使用 “{ { block.super }}“ 变量.这在你希望在父模板的内容之后添加一些内容时会很有用.(你不必完全覆盖父模板的内容.)自定义标签及过滤器库
某些应用提供自定义标签和过滤器库. 要在一个模板中访问它们, 使用 {% load %} 标签:
{% load comments %} {% comment_form for blogs.entries entry.id with is_public yes %}
{% load %} 标签可接受空隔分隔的多个库的名字作为参数.{% load comments i18n %}
当你载入一个自定义标签或过滤器库, 只有当前模板可以使用这些标签/过滤器 — 继承链中不论是父模板还是子模板都不能使用使用这些标签和过滤器.
内建标签参考
block:定义一个能被子模板覆盖的块.
注释.模板引擎会忽略掉 {% comment %} 和 {% endcomment %} 之间的所有内容.
cycle:在循环时轮流使用给定的字符串列表中的值.
在循环之外, 在你第一次调用它时给这些字符串值定义一个不重复的名字,然后在循环中使用这个名字:
你可以使用任意数量的逗号分隔的值.只有一点请你注意,不要在值与值之间放任何空隔–仅仅只有一个逗号即可.
debug:输出完整的调试信息,包括当前的上下文及导入的模块信息.
filter:用来过滤变量的值
{% filter escape|lower %}
文本将被 HTML-转义, 并且全部转化为小写
{% end过滤器 %}
firstof:输出传递给它的第一个不是 False 的变量值. 如果所有的变量都是 False 那就不输出任何东西.
示例:
{% firstof var1 var2 var3 %}
它等价于:{% if var1 %}
{ { var1 }}{% else %}{% if var2 %} { { var2 }}{% else %}{% if var3 %} { { var3 }}{% endif %}{% endif %}{% endif %}<ul>
{% for athlete in athlete_list %}
<li>{
{ athlete.name }}</li>{% endfor %}
</ul>
{% if athlete_list %}
Number of athletes: {
{ athlete_list|length }}{% else %}
No athletes.
{% endif %}
ifchanged:检查一个变量自上次循环之后是否发生了改变
and,“or“ 或 not
ifequal:若两个参数相等,输出一个内容块.
{% ifequal user.id comment.user_id %} …{% endifequal %}
ifnotequal:类似 ifequal, 只是它用来测试两个参数是否不等.
include:载入一个模板并根据当前上下文渲染它.用于在一个模板中包含其它模板.
模板名字可以是一个变量,也可以是一个字符串(带引号的字符串,无所谓单引号还是双引号).
{% include “foo/bar.html” %}
{% include template_name %}
load:装入一个自定义模板标签集.
now:显示当前日期, 根据给定的字符串决定输出格式.使用和 PHP 的 date() 函数一样的格式码。
spaceless:将HTML标签之间的空白格式化为一个空格. 空白包括空格,换行,制表符.
ssi:在页面中输出给定文件的内容.
{% ssi /home/html/ljworld.com/includes/right_generic.html %} 如果提供了可选的 “parsed” 参数, 被包含文件的内容会使用当前的上下文作为模板代码进行求值处理:
{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
要创建柱形图的话, 这个标签计算给定值与最大值的比率再乘以100,四舍五入为整数,最后输出这个整数.
<img src=”bar.gif” height=”10″ width=”{% widthratio this_value max_value 100 %}” />