django 内建标签与过滤器(一)

autoescape

控制自动转义是否可用。
on:开启自动转义
off:关闭自动转义
当自动转义生效时,所有变量内容会被转义成HTML输出(在所有过滤器生效后)这等同与手动将escape筛选器应用于每个变量。

views.py
from django.utils.safestring import mark_safe
str1 = "<a href='#'>111</a>"
str2 = "<p>222</p>"
str3 = mark_safe("<span>333</span>")

{% autoescape off %}  #关闭自动转义,标签内的每个变量都会安全输出
    {{ str1  }}
    {{ str2 | escape }} #escape筛选器,输出转义后内容
    {{ str3  }} #mark_safe函数,输出转义后内容
{% endautoescape %}

block

block标签常用在模板继承中,可以被子模板覆盖。

comment注释

在 {% comment %} 和 {% endcomment %},之间的内容会被忽略,作为注释。在第一个标签可以插入一个可选的记录。 比如,当要注释掉一些代码时,可以用此来记录代码被注释掉的原因。
简单示例:

<p>正常代码</p>
{% comment "注释原因" %}
    <p>被注释的代码</p>
{% endcomment %}

comment标签不能嵌套使用。

csrf_token

{% csrf_token %}
这个标签用于跨站请求伪造保护。

cycle

每当这个标签被访问,则传出一个它的可迭代参数的元素。第一次访问返回第一个元素,第二次访问返回第二个参数,以此类推.一旦所有的变量都被访问过了,就会回到最开始的地方,重复下去。
这个标签在循环中特别有用:

{% for o in some_list %}
    <tr class="{% cycle 'row1' 'row2' %}">
        ...
    </tr>
{% endfor %}

第一次迭代产生的HTML引用了 row1类,第二次则是row2类,第三次 又是row1 类,如此类推。
你也可以使用变量,例如,如果你有两个模版变量, rowvalue1和rowvalue2, 你可以让他们的值像这样替换:

{% for o in some_list %}
    <tr class="{% cycle rowvalue1 rowvalue2 %}">
        ...
    </tr>
{% endfor %}

你能混合使用变量和字符串:

{% for o in some_list %}
    <tr class="{% cycle 'row1' rowvalue2 'row3' %}">
        ...
    </tr>
{% endfor %}

在某些情况下,您可能需要连续引用一个当前循环的值,而不前进到下一个循环值。要达到这个目的,只需使用“as”来给{% cycle %}一个别名。
从那时起(设置别名后),你可以通过将别名作为一个模板变量进行引用,从而随意在模板中插入当前循环的值。如果要将循环值移动到独立于原始cycle标记的下一个值,可以使用另一个cycle标记并指定变量的名称。所以,下面的模板:

<tr>
    <td class="{% cycle 'row1' 'row2' as rowcolors %}">...</td>
    <td class="{{ rowcolors }}">...</td>
</tr>
<tr>
    <td class="{% cycle rowcolors %}">...</td>
    <td class="{{ rowcolors }}">...</td>
</tr>

将输出:

<tr>
    <td class="row1">...</td>
    <td class="row1">...</td>
</tr>
<tr>
    <td class="row2">...</td>
    <td class="row2">...</td>
</tr>

cycle 标签中,通过空格分割,你可以使用任意数量的值。被包含在单引号 (')或者双引号 (") 中的值被认为是可迭代字符串,相反,没有被引号包围的值被当作模版变量。
默认情况下,当你在cycle标签中使用as 关键字时,关于{% cycle %}的使用,会启动cycle并且直接产生第一个值。如果你想要在嵌套循环中或者included模版中使用这个值,那么将会遇到困难。如果你只是想要声明cycle,但是不产生第一个值,你可以添加一个silent关键字来作为cycle标签的最后一个关键字。例如:

{% for obj in some_list %}
    {% cycle 'row1' 'row2' as rowcolors silent %}
    <tr class="{{ rowcolors }}">{% include "subtemplate.html" %}</tr>
{% endfor %}

这将输出<tr>元素的列表,其中class在row1和row2之间交替。子模板将在其上下文中访问rowcolors,并且该值将匹配包围它的<tr>的类。如果省略silent关键字,则row1和row2将作为正常文本发出。
当在循环定义上使用silent关键字时,静默将自动应用于该特定周期标记的所有后续使用。The following template would output nothing, even though the second call to {% cycle %} doesn’t specify silent:

{% cycle 'row1' 'row2' as rowcolors silent %}
{% cycle rowcolors %}

debug

{% debug %}
输出整个调试信息,包括当前上下文和导入的模块。

extends

表示当前模板继承自一个父模板
这个标签可以有两种用法:

  • {% extends "base.html" %} (要有引号).继承名为"base.html"的父模板
  • {% extends variable %} 使用variable的值. 如果变量被计算成一个字符串,Django将会把它看成是父模版的名字。如果变量被计算到一个Template对象,Django将会使用那个对象作为一个父模版。

filter

通过一个或多个过滤器对内容过滤。 作为灵活可变的语法,多个过滤器被管道符号相连接,且过滤器可以有参数。
注意块中所有的内容都应该包括在filter 和endfilter 标签中。
简单用例:

{% filter force_escape|lower %}
    This text will be HTML-escaped, and will appear in all lowercase.
{% endfilter %}

注意:escape和safe是不可接受的参数,而应使用autoescape标记来管理模板代码块的转义。

firstof

输出第一个不为false的参数,如果传入的参数都为false,就什么也不输出。

{% firstof var1 var2 var3 %}

等价于:

{% if var1 %}
    {{ var1 }}
{% elif var2 %}
    {{ var2 }}
{% elif var3 %}
    {{ var3 }}
{% endif %}

当然你也可以用一个默认字符串作为输出以防传入的所有变量都是False:

{% firstof var1 var2 var3 "fallback value" %}

标签auto-escapes是开启的, 你可以这样关闭auto-escaping:

{% autoescape off %}
    {% firstof var1 var2 var3 "<strong>fallback value</strong>" %}
{% endautoescape %}

如果只想要部分变量被规避,可以这样使用:

{% firstof var1 var2|safe var3 "<strong>fallback value</strong>"|safe %}

for

循环组中的每一个项目,并让这些项目在上下文中可用。

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>

可以利用{% for obj in list reversed %}反向完成循环。
如果你需要循环一个包含列表的列表,可以通过拆分每一个二级列表为一个独立变量来达到目的。 举个例子,如果你的内容包括一个叫做points的(x,y) 列表,你可以像以下例子一样输出points列表:

{% for x, y in points %}
    There is a point at {{ x }},{{ y }}
{% endfor %}

{% for key, value in dict.items %}
    {{ key }}: {{ value }}
{% endfor %}

forloop中包含了循环的序号:

Variable Description
forloop.counter The current iteration of the loop (1-indexed)
forloop.counter0 The current iteration of the loop (0-indexed)
forloop.revcounter The number of iterations from the end of the loop (1-indexed)
forloop.revcounter0 The number of iterations from the end of the loop (0-indexed)
forloop.first True if this is the first time through the loop
forloop.last True if this is the last time through the loop
forloop.parentloop For nested loops, this is the loop surrounding the current one

for ... empty

for 标签带有一个可选的{% empty %} 从句,以便在给出的组是空的或者没有被找到时,可以有所操作。

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% empty %}
    <li>Sorry, no athletes in this list.</li>
{% endfor %}
</ul>

它和下面的例子作用相等,但是更简洁、更清晰甚至可能运行起来更快:

<ul>
  {% if athlete_list %}
    {% for athlete in athlete_list %}
      <li>{{ athlete.name }}</li>
    {% endfor %}
  {% else %}
    <li>Sorry, no athletes in this list.</li>
  {% endif %}
</ul>

if

{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),这个内容块会输出:

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

上述例子中,如果athlete_list不为空,就会通过使用{{ athlete_list|length }}过滤器展示出athletes的数量。

正如你所见,if标签之后可以带有一个或者多个{% elif %} 从句,也可以带有一个{% else %}从句以便在之前的所有条件不成立的情况下完成执行。这些从句都是可选的。

布尔运算符

if标签可以使用and,or或not来测试多个变量或取消给定变量:

{% 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 %}

允许同时使用and和or子句,and的优先级高于or :

{% if athlete_list and coach_list or cheerleader_list %}

将解释如下:

if (athlete_list and coach_list) or cheerleader_list

if标签还可能使用 ==, !=, <, >, <=, >= 和 in,他们作用如下
== 相等

{% if somevar == "x" %}
  This appears if variable somevar equals the string "x"
{% endif %}

!= 不等

{% if somevar != "x" %}
  This appears if variable somevar does not equal the string "x",
  or if somevar is not found in the context
{% endif %}
>大于
{% if somevar > 0 %}
  This appears if variable somevar is greater than 0.
{% endif %}

>= 大于或等于
{% if somevar >= 1 %}
  This appears if variable somevar is greater than 1 or equal to 1.
{% endif %}

< 小于
{% if somevar < 100 %}
  This appears if variable somevar is less than 100.
{% endif %}

<= 小于或等于
{% if somevar <= 100 %}
  This appears if variable somevar is less than 100 or equal to 100.
{% endif %}

in 包含在内

{% if "bc" in "abcdef" %}
  This appears since "bc" is a substring of "abcdef"
{% endif %}

{% if "hello" in greetings %}
  If greetings is a list or set, one element of which is the string
  "hello", this will appear.
{% endif %}

{% if user in users %}
  If users is a QuerySet, this will appear if user is an
  instance that belongs to the QuerySet.
{% endif %}

not in 不包含 是in的否定操作

注意:比较运算符不能链接使用:
{% if a > b > c %}  (WRONG)
应该这样使用:
{% if a > b and b > c %}

可以在if表达式中使用过滤器:

{% if messages|length >= 100 %}
   You have lots of messages today!
{% endif %}

符合表达式
所有上述操作符可以组合以形成复杂表达式。对于这样的表达式,重要的是要知道在表达式求值时如何对运算符进行分组 - 即优先级规则。操作符的优先级从低至高如下:

  • or
  • and
  • not
  • in
  • ==, !=, <, >, <=, >=

(这完全依据Python)。所以,例如,下面的复杂标签:

{% if a == b or c == d and e %}

将被解释为:

(a == b) or ((c == d) and e)

如果你想要不同的优先级,为了清楚起见和可读性,那么你需要使用嵌套的if标签。

ifchanged

检查一个值是否在上一次的迭代中改变。
{% ifchanged %} 块标签用在循环里。它可能有两个用处:

  1. 检查它已经渲染过的内容中的先前状态。并且只会显示发生改变的内容。例如, 以下的代码是输出days的列表项,不过它只会输出被修改过月份的项:
<h1>Archive for {{ year }}</h1>

{% for date in days %}
    {% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
    <a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
{% endfor %}
  1. 如果标签内被给予多个值时,则会比较每一个值是否与上一次不同。例如,以下显示每次更改时的日期,如果小时或日期已更改,则显示小时:
{% for date in days %}
    {% ifchanged date.date %} {{ date.date }} {% endifchanged %}
    {% ifchanged date.hour date.date %}
        {{ date.hour }}
    {% endifchanged %}
{% endfor %}

ifchanged标记也可以采用可选的{% else %} 将显示如果值没有改变:

{% for match in matches %}
    <div style="background-color:
        {% ifchanged match.ballot_id %}
            {% cycle "red" "blue" %}
        {% else %}
            gray
        {% endifchanged %}
    ">{{ match }}</div>
{% endfor %}

ifequal/ifnotequal

如果给定的两个参数是相等的,则显示被标签包含的内容,也可以包含 {% else %} 标签选项。

{% ifequal user.username "adrian" %}
    ...
{% else %}
    ...
{% endifequal %}

{% ifnotequal user.username "adrian" %}
    ...
{% else %}
    ...
{% endifnotequal %}

ifequal标记的替代方法是使用if标记和==运算符。
ifnotequal标记的替代方法是使用if标记和!=运算符。

include

加载模板并以标签内的参数渲染。这是一种可以引入别的模板的方法。
模板名可以是变量或者是硬编码的字符串,可以用单引号也可以是双引号.
下面这个示例包括模板“foo/bar.html”的内容:

{% include "foo/bar.html" %}

此示例包括其名称包含在变量template_name中的模板的内容:

{% include template_name %}
Changed in Django 1.7:
变量也可以是任何实现了render() 方法接口的对象,这个对象要可以接收上下文(context)。
这就允许你在context中引用一个已经被编译过的Template。

被包含的模板在包含它的模板的上下文中渲染。下面这个示例生成输出“Hello, John!”:

  • 上下文:变量person设置为“John”,变量greeting设置为“Hello”。
  • 模板:{% include "name_snippet.html" %}
  • name_snippet.html模板:{{ greeting }}, {{ person|default:"friend" }}!

你可以使用关键字参数将额外的上下文传递到模板:

{% include "name_snippet.html" with person="Jane" greeting="Hello" %}

如果要仅使用提供的变量(或根本不使用变量)来渲染上下文,请使用only选项。所包含的模板没有其他变量可用:

{% include "name_snippet.html" with greeting="Hi" only %}

注意:
include标签应该被理解为是一种"将子模版渲染并嵌入HTML中"的变种方法,而不是认为是"解析子模版并在被父模版包含的情况下展现其被父模版定义的内容".这意味着在不同的被包含的子模版之间并不共享父模版的状态,每一个子包含都是完全独立的渲染过程.
Block模块在被包含 之前 就已经被执行. 这意味着模版在被包含之前就已经从另一个block扩展并 已经被执行并完成渲染 - 没有block模块会被include引入并执行,即使父模版中的扩展模版.

load

加载自定义模板标签集。
举个例子, 下面这模板将会从package包中载入所有somelibrary 和otherlibrary 中已经注册的标签和过滤器:

{% load somelibrary package.otherlibrary %}

你还可以使用from参数从库中选择性加载单个过滤器或标记。在下面这个示例中,名为foo和bar的模板标签/过滤器将从somelibrary加载:

{% load foo bar from somelibrary %}

lorem

展示随机的“lorem ipsum”拉丁文本. 这个标签是用来在模版中提供文字样本以供测试用的.
1.8版本之前该标签之前位于django.contrib.webdesign中。
用法:

{% lorem [count] [method] [random] %}
Argument Description
count A number (or variable) containing the number of paragraphs or words to generate (default is 1).
method Either w for words, p for HTML paragraphs or b for plain-text paragraph blocks (default is b).
random The word random, which if given, does not use the common paragraph (“Lorem ipsum dolor sit amet...”) when generating text.

例子:

  • {% lorem %}将输出常见的“lorem ipsum”段落。
  • {% lorem 3 p %} 输出常见的“lorem ipsum”段落和两个随机段落,每个段落包含在HTML <p>标签中。
  • {% lorem 2 w random %} / t6>将输出两个随机拉丁字。

now

显示最近的日期或事件,可以通过给定的字符串格式显示。此类字符串可以包含格式说明符字符,如date过滤器部分中所述。
例:

{% now "" %} ---Nov. 5, 2017
{% now "Y-m-d" %}---2017-11-05
{% now "jS F Y H:i" %}---5th November 2017 08:48
{% now "SHORT_DATETIME_FORMAT" %} --- 11/05/2017 8:50 a.m.

注意!,如果你想要使用“raw”值,你能够反斜杠转义一个格式化字符串。在这个例子中,“o”和“f”都是反斜杠转义,因为如果不这样,会分别显示年和时间:

It is the {% now "jS \o\f F" %}
#It is the 5th of November

传递的格式也可以是预定义的DATE_FORMAT,DATETIME_FORMAT,SHORT_DATE_FORMAT或SHORT_DATETIME_FORMAT之一。预定义的格式可能会因当前语言环境和格式本地化的启用而有所不同。

 Django 1.8之后添加了使用“as”语法的能力。

templatetag

输出用于构成模板标记的语法字符之一。
由于模板系统没有“转义”的概念,为了显示模板标签中使用的一个位,必须使用{% templatetag %}标记。
参数指定要输出哪个模板位:

Argument Outputs
openblock {%
closeblock %}
openvariable {{
closevariable }}
openbrace {
closebrace }
opencomment {#
closecomment #}

样品用量:
{% templatetag openblock %} url 'entry_list' {% templatetag closeblock %}

url

返回一个绝对路径的引用(不包含域名的URL),该引用匹配一个给定的视图函数和一些可选的参数。在解析后返回的结果路径字符串中,每个特殊字符将使用iri_to_uri()编码。
这是一种不违反DRY原则的输出链接的方式,它可以避免在模板中硬编码链接路径。
使用方法:

{% url 'some-url-name' v1 v2 %}
{% url 'some-url-name' arg1=v1 arg2=v2 %}

举例:

<a href="{% url 'teacher_info' 1 %}">教师信息</a>

注意,如果填写的网址不存在,您会收到NoReverseMatch异常,这会导致您的网站显示错误网页。
如果您希望在不显示网址的情况下检索网址,则可以使用略有不同的调用:

{% url 'teacher_info111' 3 as info %}
<a href="{{info}}">教师信息</a>

这种{% url ...as var%}语法不会导致错误,如果视图丢失。实际上,您将使用此链接来链接到可选的视图:

{% url 'some-url-name' as the_url %}
{% if the_url %}
  <a href="{{ the_url }}">Link to optional stuff</a>
{% endif %}

如果您要检索名称空间网址,请指定完全限定名称:

{% url 'myapp:view-name' %}

警告:不要忘记在函数路径或模式名称周围加引号,否则值将被解释为上下文变量!

verbatim

停止模版引擎在该标签中的渲染

{% verbatim %}
    {{ list1 }}
{% endverbatim %}

#也可以委派一个自定义的标签名
{% verbatim myblock %}
    {{ list1 }}
{% endverbatim myblock %}

widthratio

可以创建进度条等,此标签计算给定值与最大值的比率,然后将该比率应用于常量。

{% widthratio this_value max_value max_width %}

如果this_value是100,max_value是200,并且max_width是50,则上述值是25(因为100 / 200 = 0.5;50 * 0.5 = 25)。
Django1.7版本后增加了as用法:

{% widthratio 100 200 50 as x %}
{{ x }}

with

使用一个简单地名字缓存一个复杂的变量,当你需要使用一个“昂贵的”方法(比如访问数据库)很多次的时候是非常有用的。

{% with total=business.employees.count %}
    {{ total }} employee{{ total|pluralize }}
{% endwith %}

你可以分配多个上下文变量:

{% with alpha=1 beta=2 %}
    ...
{% endwith %}

add

{{ value|add:"2" }}把add后的参数加给value
如果 value 为 4,则会输出 6.
过滤器首先会强制把两个值转换成Int类型。如果强制转换失败, 它会试图使用各种方式吧两个值相加。它会使用一些数据类型 (字符串, 列表, 等等.) 其他类型则会失败. Day of the month, 2 digits with leading zeros.

{{ first|add:second }}

first 是 [1, 2, 3] ,second 是 [4, 5, 6], 将会输出 [1, 2, 3, 4, 5, 6].

addslashes

在引号前面加上斜杆。例如,用于在CSV中转义字符串。

{{ value|addslashes }}

如果value 是 "I'm using Django", 输出将变成 "I'm using Django".

cut

移除value中所有的与给出的变量相同的字符串

{{ value|cut:" " }}

如果value为“String with spaces”,输出将为"Stringwithspaces"。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容