Django 模板语言

简介:

关于方法调用 
方法调用要比其他的查询稍微复杂一点,下面是需要记住的几点: 
1,在方法查询的时候,如果一个方法触发了异常,这个异常会传递从而导致渲染失 
败,但是如果异常有一个值为True的silent_variable_failure属性,这个变量会渲染成空string:

代码
  1. >>> t = Template("My name is {{ person.first_name }}.")   
  2. >>> class PersonClas3:   
  3. ...      def first_name(self):   
  4. ...          raise AssertionError, "foo"  
  5. >>> p = PersonClass3()   
  6. >>> t.render(Context({"person": p}))   
  7. Traceback (most recent call last):   
  8. ...   
  9. AssertionError: foo   
  10. >>> class SilentAssetionError(AssertionError):   
  11. ...      silent_variable_failure = True   
  12. >>> class PersonClass4:   
  13. ...      def first_name(self):   
  14. ...          raise SilentAssertionError   
  15. >>> p = PersonClass4()   
  16. >>> t.render(Context({"person": p}))   
  17. "My name is ."  

2,方法调用仅仅在它没有参数时起作用,否则系统将继续查找下一个类型(列表索引查询) 
3,显然一些方法有副作用,让系统访问它们是很愚蠢的,而且很可能会造成安全性问 
题。 
例如你有一个BankAccount对象,该对象有一个delete()方法,模板系统不应该允许做下面的事情 
I will now delete this valuable data. {{ account.delete }} 
为了防止这种状况,可以在方法里设置一个方法属性alters_data 
如果设置了alters_data=True的话模板系统就不会执行这个方法: 
代码
  1. def delete(self):   
  2.      # Delete the account   
  3. delete.alters_data = True  

 

不合法的变量怎样处理 
默认情况下如果变量不存在,模板系统会把它渲染成空string,例如:

代码
  1. >>> from django.template import Template, Context   
  2. >>> t = Template('Your name is {{ name }}.')   
  3. >>> t.render(Context())   
  4. 'Your name is .'   
  5. >>> t.render(Context({'var': 'hello'}))   
  6. 'Your name is .'   
  7. >>> t.render(Context({'NAME': 'hello'}))   
  8. 'Your name is .'   
  9. >>> t.render(Context({'Name': 'hello'}))   
  10. 'Your name is .'  

系统会静悄悄地显示错误的页面,而不是产生一个异常,因为这种情况通常是人为的错误。 
在现实情形下,一个web站点因为一个模板代码语法的错误而变得不可用是不可接受的。 
我们可以通过设置Django配置更改Django的缺省行为,第10章扩展模板引擎会我们会讨论这个

 

玩玩Context对象 
大多数情况下你初始化Context对象会传递一个字典给Context() 
一旦你初始化了Context,你可以使用标准Python字典语法增减Context对象的items:

代码
  1. >>> from django.template import Context   
  2. >>> c = Context({"foo""bar"})   
  3. >>> c['foo']   
  4. 'bar'   
  5. >>> del c['foo']   
  6. >>> c['foo']   
  7. ''  
  8. >>> c['newvariable'] = 'hello'   
  9. >>> c['newvariable']   
  10. 'hello'  

Context对象是一个stack,你可以push()和pop() 
如果你pop()的太多的话它将触发django.template.ContextPopException: 
代码
  1. >>> c = Context()   
  2. >>> c['foo'] = 'first level'   
  3. >>> c.push()   
  4. >>> c['foo'] = 'second level'   
  5. >>> c['foo']   
  6. 'second level'   
  7. >>> c.pop()   
  8. >>> c['foo']   
  9. 'first level'   
  10. >>> c['foo'] = 'overwritten'   
  11. >>> c['foo']   
  12. 'overwritten'   
  13. >>> c.pop()   
  14. Traceback (most recent call last):   
  15. ...   
  16. django.template.ContextPopException  

第10章你会看到使用Context作为stack自定义模板标签

 

模板标签和过滤器基础 
我们已经提到模板系统使用内建的标签和过滤器 
这里我们看看常见的,附录6包含了完整的内建标签和过滤器,你自己熟悉那个列表来了解可以做什么是个好主意

if/else 
{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值 
系统则会显示{% if %}和{% endif %}间的所有内容:

代码
  1. {% if today_is_weekend %}   
  2.     <p>Welcome to the weekend!</p>  
  3. {% else %}   
  4.     <p>Get back to work.</p>  
  5. {% endif %}  

{% if %}标签接受and,or或者not来测试多个变量值或者否定一个给定的变量,例如: 
代码
  1. {% if athlete_list and coach_list %}   
  2.      Both athletes and coaches are available.   
  3. {% endif %}   
  4. {% if not athlete_list %}   
  5.      There are no athletes.   
  6. {% endif %}   
  7. {% if athlete_list or coach_list %}   
  8.      There are some athletes or some coaches.   
  9. {% endif %}   
  10. {% if not athlete_list or coach_list %}   
  11.      There are no athletes or there are some coaches.   
  12. {% endif %}   
  13. {% if athlete_list and not coach_list %}   
  14.      There are some athletes and absolutely no coaches.   
  15. {% endif %}  

{% if %}标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的: 
代码
  1. {% if athlete_list and coach_list or cheerleader_list %}  

如果你想结合and和or来做高级逻辑,只需使用嵌套的{% if %}标签即可: 
代码
  1. {% if athlete_list %}   
  2.      {% if coach_list or cheerleader_list %}   
  3.          We have athletes, and either coaches or cheerleaders!   
  4.      {% endif %}   
  5. {% endif %}  

多次使用同一个逻辑符号是合法的: 
代码
  1. {% if athlete_list or coach_list or parent_list or teacher_list %}  

没有{% elif %}标签,使用嵌套的{% if %}标签可以做到同样的事情: 
代码
  1. {% if athlete_list %}   
  2.     <p>Here are the athletes: {{ athlete_list }}.</p>  
  3. {% else %}   
  4.     <p>No athletes are available.</p>  
  5.      {% if coach_list %}   
  6.         <p>Here are the coaches: {{ coach_list }}.</p>  
  7.      {% endif %}   
  8. {% endif %}  

确认使用{% endif %}来关闭{% if %}标签,否则Django触发TemplateSyntaxError

 

for 
{% for %}标签允许你按顺序遍历一个序列中的各个元素 
Python的for语句语法为for X in Y,X是用来遍历Y的变量 
每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容 
例如,显示给定athlete_list变量来显示athlete列表:

代码
  1. <ul>  
  2. {% for athlete in athlete_list %}   
  3.     <li>{{ athlete.name }}</li>  
  4. {% endfor %}   
  5. </ul>  

在标签里添加reversed来反序循环列表: 
代码
  1. {% for athlete in athlete_list reversed %}   
  2. ...   
  3. {% endfor %}   
  4. {% for %}标签可以嵌套:   
  5. {% for country in countries %}   
  6.     <h1>{{ country.name }}</h1>  
  7.     <ul>  
  8.      {% for city in country.city_list %}   
  9.         <li>{{ city }}</li>  
  10.      {% endfor %}   
  11.     </ul>  
  12. {% endfor %}  

系统不支持中断循环,如果你想这样,你可以改变你想遍历的变量来使得变量只包含你想遍历的值 
类似的,系统也不支持continue语句,本章后面的“哲学和限制”会解释设计的原则 
{% for %}标签内置了一个forloop模板变量,这个变量含有一些属性可以提供给你一些关于循环的信息 
1,forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1,例如: 
代码
  1. {% for item in todo_list %}   
  2.     <p>{{ forloop.counter }}: {{ item }}</p>  
  3. {% endfor %}  

2,forloop.counter0类似于forloop.counter,但它是从0开始计数,第一次循环设为0 
3,forloop.revcounter表示循环中剩下的items数量,第一次循环时设为items总数,最后一次设为1 
4,forloop.revcounter0类似于forloop.revcounter,但它是表示的数量少一个,即最后一次循环时设为0 
5,forloop.first当第一次循环时值为True,在特别情况下很有用: 
代码
  1. {% for object in objects %}   
  2.      {% if forloop.first %}<li class="first">{% else %}<li>{% endif %}   
  3.      {{ object }}   
  4.     </li>  
  5. {% endfor %}  

6,forloop.last当最后一次循环时值为True 
代码
  1. {% for link in links %}{{ link }}{% if not forloop.last %} | {% endif %}{% endfor %}  

7,forloop.parentloop在嵌套循环中表示父循环的forloop: 
代码
  1. {% for country in countries %}   
  2.     <table>  
  3.      {% for city in country.city_list %}   
  4.         <tr>  
  5.             <td>Country #{{ forloop.parentloop.counter }} </td>  
  6.             <td>City #{{ forloop.counter }}</td>  
  7.             <td>{{ city }}</td>  
  8.         </tr>  
  9.      {% endfor %}   
  10.     </table>  
  11. {% endfor %}  

富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了 
如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它 
Django会在for标签的块中覆盖你定义的forloop变量的值 
在其他非循环的地方,你的forloop变量仍然可用 
我们建议模板变量不要使用forloop,如果你需要这样做来访问你自定义的forloop,你可以使用forloop.parentloop

 

ifequal/ifnotequal 
Django模板系统并不是一个严格意义上的编程语言,所以它并不允许我们执行Python语句 
(我们会在‘哲学和限制‘一节详细讨论)。 
然而在模板语言里比较两个值并且在他们一致的时候显示一些内容,确实是一个在常见不过的需求了——所以Django提供了ifequal标签。 
{% ifequal %}比较两个值,如果相等,则显示{% ifequal %}和{% endifequal %}之间的所有内容:

代码
  1. {% ifequal user currentuser %}   
  2.     <h1>Welcome!</h1>  
  3. {% endifequal %}  

参数可以是硬编码的string,单引号和双引号均可,下面的代码是合法的: 
代码
  1. {% ifequal section 'sitenews' %}   
  2.     <h1>Site News</h1>  
  3. {% endifequal %}   
  4. {% ifequal section "community" %}   
  5.     <h1>Community</h1>  
  6. {% endifequal %}  

和{% if %}一样,{% ifequal %}标签支持{% else %} 
代码
  1. {% ifequal section 'sitenews' %}   
  2.     <h1>Site News</h1>  
  3. {% else %}   
  4.     <h1>No News Here</h1>  
  5. {% endifequal %}  

其它的模板变量,strings,integers和小数都可以作为{% ifequal %}的参数: 
代码
  1. {% ifequal variable 1 %}   
  2. {% ifequal variable 1.23 %}   
  3. {% ifequal variable 'foo' %}   
  4. {% ifequal variable "foo" %}  

其它的Python类型,如字典、列表或booleans不能硬编码在{% ifequal %}里面,下面是不合法的: 
代码
  1. {% ifequal variable True %}   
  2. {% ifequal variable [123,]%}   
  3. {% ifequal variable {'key': 'value'} %  

如果你需要测试某个变量是true或false,用{% if %}即可

 

注释 
和HTML或编程语言如Python一样,Django模板语言允许注释{# #},如:

代码
  1. {# This is a comment #}  

模板渲染时注释不会输出,一个注释不能分成多行 
下面的模板渲染时会和模板中的内容一样,注释标签不会解析成注释 
This is a {# comment goes here 
and spans another line #} 
test.

 

过滤器 
本章前面提到,模板过滤器是变量显示前转换它们的值的方式,看起来像下面这样:

代码
  1. {{ name|lower }}  

这将显示通过lower过滤器过滤后{{ name }}变量的值,它将文本转换成小写 
使用(|)管道来申请一个过滤器 
过滤器可以串成链,即一个过滤器的结果可以传向下一个 
下面是escape文本内容然后把换行转换成p标签的习惯用法: 
代码
  1. {{ my_text|escape|linebreaks }}  

有些过滤器需要参数,需要参数的过滤器的样子: 
代码
  1. {{ bio|truncatewords:"30" }}  

这将显示bio标量的前30个字,过滤器参数一直使用双引号 
下面是一些最重要的过滤器: 
1,addslashed,在任何后斜线,单引号,双引号前添加一个后斜线 
当你把一些文本输出到一个JavaScript字符串时这会十分有用 
2,date,根据一个格式化string参数来格式化date或datetime对象,例如: 
代码
  1. {{ pub_date|date:"F j, Y" }}  

格式化string会在附录6定义 
3,escape,避免给定的string里出现and符,引号,尖括号 
当你处理用户提交的数据和确认合法的XML和XHTML数据时这将很有用 
escape将作如下的一些转换: 
代码
  1. Converts & to &amp;   
  2. Converts < to &lt;   
  3. Converts > to &gt;   
  4. Converts "(双引号) to &quot;   
  5. Converts '(单引号) to &#39;   

4,length,返回值的长度,你可以在一个list或string上做此操作 
或者在任何知道怎样决定自己的长度的Python对象上做此操作(即有一个__len__()方法的对象)
===================

变量

变量的形式:{{ 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.

复制代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>{% block title %}久久寻网{% endblock %}</title>
<link type="text/css" rel="stylesheet" href="style.css" />
</head>
<body>
    <div id="side">
        {% block side %}
        <ul>
            <li><a href="/index.html">主页</a></li>
            <li><a href="/blog/index.html">博客</a></li>
        </ul>
        {% endblock %}
    </div>
    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>
复制代码

我们称它为 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 %}” />

本文转自博客园知识天地的博客,原文链接:Django 模板语言,如需转载请自行联系原博主。

相关文章
|
6月前
|
SQL 前端开发 JavaScript
Python 教程之 Django(10)模板
Python 教程之 Django(10)模板
62 0
|
2月前
|
Java C++ Python
django 模板 过滤器
django 模板 过滤器
|
3月前
|
前端开发 JavaScript 数据库
python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器
python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器
|
3月前
|
JSON 数据处理 API
Django后端架构开发:视图与模板的正确使用
Django后端架构开发:视图与模板的正确使用
24 1
|
3月前
|
前端开发 Python
Django模板
【8月更文挑战第19天】
30 3
|
3月前
|
自然语言处理 前端开发 数据处理
Django的模板系统
【8月更文挑战第13天】
28 2
|
3月前
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
95 0
|
3月前
|
前端开发 数据处理 开发者
解锁Django模板系统终极奥义!揭秘高效前端渲染秘籍,让你的网站秒变炫酷黑科技!
【8月更文挑战第31天】Django作为Python的高级Web框架,内置的模板系统支持动态HTML渲染。本文通过在线书店案例,详细介绍Django模板系统的设置与高效渲染技巧,包括创建模板文件、编写视图函数及URL配置。通过合理使用过滤器、深度查询和模板继承等技巧,提升前端渲染效率和安全性,优化Web应用开发流程。
22 0
|
3月前
|
安全 JavaScript 前端开发
Django入门到放弃之模板及标签
Django入门到放弃之模板及标签
|
5月前
|
缓存 运维 Serverless
Serverless 应用引擎产品使用合集之基于django应用模板创建的FC,如何配置数据库
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。