Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

前端之家收集整理的这篇文章主要介绍了Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中。

Highlighter sh-gutter">
Highlighter_998507" class="SyntaxHighlighter python">
It is now %s."

尽管这种技术便于解释视图是如何工作的,但直接将HTML硬编码到你的视图里却并不是一个好主意。 让我们来看一下为什么:

    页面设计进行的任何改变都必须对 Python 代码进行相应的修改站点设计的修改往往比底层 Python 代码修改要频繁得多,因此如果可以在不进行 Python 代码修改的情况下变更设计,那将会方便得多。

    代码编写和 HTML 设计是两项不同的工作,大多数专业的网站开发环境都将他们分配给不同的人员(甚至不同部门)来完成。 设计者和HTML/CSS的编码人员不应该被要求去编辑Python的代码来完成他们的工作。

    代码和设计人员制作模板两项工作同时进行的效率是最高的,远胜于让一个人等待另一个人完成对某个既包含 Python又包含 HTML 的文件的编辑工作。

基于这些原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护。 我们可以使用 Django的模板系统(Template System)来实现这种模式,这就是本章要具体讨论的问题。

python的模板:HTML代码+模板语法

模版包括在使用时会被值替换掉的,和控制模版逻辑的标签

函数
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; ================================django模板<a href="/tag/xiugai/" target="_blank" class="keywords">修改</a>的视图<a href="/tag/hanshu/" target="_blank" class="keywords">函数</a></span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; from django.template import Template,Context</span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; now=datetime.datetime.now()</span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')</span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; #t=get_template('current_datetime.html')</span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; c=Context({'current_date':str(now)})</span>
<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; html=t.render(c)</span>
<span style="color: #008000;"&gt;#

<span style="color: #008000;">#<span style="color: #008000;"> return HttpResponse(html)

<span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt;另一种写法(推荐)</span>
<span style="color: #0000ff;"&gt;import</span><span style="color: #000000;"&gt; datetime
now</span>=<span style="color: #000000;"&gt;datetime.datetime.now()
</span><span style="color: #0000ff;"&gt;return</span> render(req,<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;current_datetime.html</span><span style="color: #800000;"&gt;'</span>,{<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;current_date</span><span style="color: #800000;"&gt;'</span>:str(now)[:19]})</pre>

<h1 class="line" data-line="50">模板语法之变量
<p id="cn88" class="cn">在 Django 模板中遍历复杂数据结构的关键是句点字符 .


<p class="cn">语法:


<p class="cn">语法:


<div class="cnblogs_Highlighter sh-gutter">

Highlighter_338911" class="SyntaxHighlighter python">

views:

Highlighter sh-gutter">
Highlighter_977621" class="SyntaxHighlighter python">
自定义类对象
#这种方法只能用在键和值的变量名相同的情况下,且会导入所以变量,即使不需要用到的也好被导入

</td>

</tr>

</table>

template:

Highlighter sh-gutter">
Highlighter_50072" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">

{{s}}<<code class="python keyword">/<code class="python plain">h4>


<div class="line number2 index1 alt1"><code class="python plain">

列表:{{ l.<code class="python value">0 <code class="python plain">}}<<code class="python keyword">/<code class="python plain">h4>


<div class="line number3 index2 alt2"><code class="python plain">

列表:{{ l.<code class="python value">2 <code class="python plain">}}<<code class="python keyword">/<code class="python plain">h4>


<div class="line number4 index3 alt1"><code class="python plain">

字典:{{ dic.name }}<<code class="python keyword">/<code class="python plain">h4>


<div class="line number5 index4 alt2"><code class="python plain">

日期:{{ date.year }}<<code class="python keyword">/<code class="python plain">h4>


<div class="line number6 index5 alt1"><code class="python plain">

类对象列表:{{ person_list.<code class="python value">0.name <code class="python plain">}}<<code class="python keyword">/<code class="python plain">h4>

</td>

</tr>

</table>

注意:方法(无参数方法)。

Highlighter sh-gutter">
Highlighter_811278" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">

字典:{{ dic.name.upper }}<<code class="python keyword">/<code class="python plain">h4>

</td>

</tr>

</table>

模板之过滤器

语法:

Highlighter sh-gutter">
Highlighter_44879" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{obj|filter__name:param}}

</td>

</tr>

</table>

default

如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:

Highlighter sh-gutter">
Highlighter_441950" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|default:
<code class="python string">"nothing"
<code class="python plain">}}

</td>

</tr>

</table>

length

返回值的长度。它对字符串和列表都起作用。例如:

Highlighter sh-gutter">
Highlighter_969892" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|length }}

</td>

</tr>

</table>

如果 value 是 ['a','b','c','d'],那么输出是 4。

filesizeformat

将值格式化为一个 “人类可读的” 文件尺寸 (例如,等等)。例如:

Highlighter sh-gutter">
Highlighter_992783" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|filesizeformat }}

</td>

</tr>

</table>

如果value是 123456789,输出将会是117.7 MB。  

date

如果 value=datetime.datetime.now(),将返回当前时间的年-月-日格式

Highlighter sh-gutter">
Highlighter_358195" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|date:
<code class="python string">"Y-m-d"
<code class="python plain">}}  

</td>

</tr>

</table>

如果value="hello world",则结果为ello worl (也是顾头不顾尾)

Highlighter sh-gutter">
Highlighter_691157" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|
<code class="python functions">slice
<code class="python plain">:
<code class="python string">"2:-1"
<code class="python plain">}}

</td>

</tr>

</table>

数量,那么会被截断。用法相同)

参数:

Highlighter sh-gutter">
Highlighter_503161" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|truncatechars:
<code class="python value">3
<code class="python plain">}}

</td>

</tr>

</table>

输出将为

标签和JS等语法标签进行自动转义,原因显而易见,这样是为了安全。但是有的时候我们可能不希望这些HTML元素被转义,比如我们做一个内容管理系统,后台添加文章中是经过修饰的,这些修饰可能是通过一个类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:

Highlighter sh-gutter">
Highlighter_488928" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">value
<code class="python keyword">=
<code class="python string">"<a href="
<code class="python string">">点击"

</td>

</tr>

</table>

Highlighter sh-gutter">
Highlighter_63798" class="SyntaxHighlighter python">

</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="python plain">{{ value|safe}}

</td>

</tr>

</table>

这里简单介绍一些常用的模板的过滤器,

模板之标签 

标签看起来像是这样的:{% tag %}。标签比变量更加复杂:一些在输出中创建文本,一些通过循环或逻辑来控制流程,一些加载其后的变量将使用到的额外信息到模版中。

一些标签需要开始和结束标签 (例如{% tag %}...标签 内容 ... {% endtag %})。

for标签

遍历每一个元素:

{{ person.name }}

可以利用反向完成循环。

遍历一个字典:

{{ key }}:{{ val }}

注:

forloop.counter forloop.counter0 forloop.revcounter forloop.revcounter0 forloop.first forloop.last

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

{{ person.name }}{% empty %}
<span style="color: #0000ff;"><
<span style="color: #800000;">p
<span style="color: #0000ff;">>
sorry,no person here<span style="color: #0000ff;"></
<span style="color: #800000;">p
<span style="color: #0000ff;">><span style="color: #000000;">
{% endfor %}

if 标签

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

{% if num > 100 or num 无效 80 and num 优秀凑活吧

=,<=,>,< 这些比较都可以在模板中使用

注意:比较符号前后必须有至少一个空格!)

方法(比如访问数据库)很多次的时候是非常有用的

标签用于跨站请求伪造保护

加上这个才能正常POST请求 <

一些有趣的用法

.获取当前用户

{{ request.user }}

如果登陆就显示内容,不登陆就不显示内容

链接 {% endif %}

自定义标签和过滤器

1、在settings中的INSTALLED_APPS配置当前app(即加上当前app的名字,如‘app01’),不然django无法找到自定义的simple_tag.

2、在app中创建templatetags模块(模块名只能是templatetags)

3、创建任意 .py 文件,如:my_tags.py

django django.utils.safestring register = template.Library() <span style="color: #008000;">#<span style="color: #008000;">register的名字是固定的,不可改变

####################以上行是固定不变要写的#############################
<span style="color: #000000;">

<span style="color: #008000;">######################定义过滤器####################
@register.filter
<span style="color: #0000ff;">def
<span style="color: #000000;"> filter_multi(v1,v2):
<span style="color: #0000ff;">return v1 <span style="color: #000000;"> v2

<span style="color: #008000;">######################定义标签#####################

<span style="color: #000000;">
@register.simple_tag
<span style="color: #0000ff;">def<span style="color: #000000;"> simple_tag_multi(v1,v2):
<span style="color: #0000ff;">return v1
<span style="color: #000000;"> v2

<span style="color: #000000;">
@register.simple_tag
<span style="color: #0000ff;">def<span style="color: #000000;"> my_input(id,arg):
result = <span style="color: #800000;">"<span style="color: #800000;"><span style="color: #800000;">" %<span style="color: #000000;">(id,arg,)
<span style="color: #0000ff;">return mark_safe(result)

4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

Highlighter sh-gutter">
Highlighter_131808" class="SyntaxHighlighter python">

5、使用simple_tag和filter(如何调用

<div class="cnblogs_code">

页面.html--------------------



标签: {% simple_tag 参数1 参数2 ... %}

{% load my_tags %<span style="color: #008000;">#<span style="color: #008000;"> num=12
{{ num|filter_multi:2 }} <span style="color: #008000;">#<span style="color: #008000;">24 #参数只能有一个
<span style="color: #000000;">
{{ num|filter_multi:<span style="color: #800000;">"<span style="color: #800000;">[22,333,4444]<span style="color: #800000;">"<span style="color: #000000;"> }}

{% simple_tag_multi 2 5 %<span style="color: #000000;">} <span style="color: #008000;">#参数不限,但不能放在if for语句中
{% simple_tag_multi num 5 %}

注意:

Highlighter sh-gutter">
Highlighter_577294" class="SyntaxHighlighter python">

自定义标签的使用:
函数的参数只能有两个,自定义标签无参数限制
标签共同使用,比如if标签自定义标签不可以。

模板继承 (extend)

Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的blocks。

通过从下面这个例子开始,可以容易的理解模版继承,首先我们写一个模板:

{% block title %}My amazing site{% endblock %}

<span style="color: #0000ff;"><<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">div <span style="color: #ff0000;">id<span style="color: #0000ff;">="sidebar"<span style="color: #0000ff;">><span style="color: #000000;">
{% block sidebar %}
<span style="color: #0000ff;"><<span style="color: #800000;">ul<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">li<span style="color: #0000ff;">><<span style="color: #800000;">a <span style="color: #ff0000;">href<span style="color: #0000ff;">="/"<span style="color: #0000ff;">>Home<span style="color: #0000ff;"></<span style="color: #800000;">a<span style="color: #0000ff;">></<span style="color: #800000;">li<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">li<span style="color: #0000ff;">><<span style="color: #800000;">a <span style="color: #ff0000;">href<span style="color: #0000ff;">="/blog/"<span style="color: #0000ff;">>Blog<span style="color: #0000ff;"></<span style="color: #800000;">a<span style="color: #0000ff;">></<span style="color: #800000;">li<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">ul<span style="color: #0000ff;">><span style="color: #000000;">
{% endblock %}
<span style="color: #0000ff;"></<span style="color: #800000;">div<span style="color: #0000ff;">>

<span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;div </span><span style="color: #ff0000;"&gt;id</span><span style="color: #0000ff;"&gt;="content"</span><span style="color: #0000ff;"&gt;></span><span style="color: #000000;"&gt;
    {% block content %}{% endblock %}
</span><span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;div</span><span style="color: #0000ff;"&gt;></span>

<span style="color: #0000ff;"></<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>

这个模版,我们把它叫作base.html它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。

在这个例子中,block标签定义了三个可以被子模版内容填充的block。block告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。

接下来,我们再写一个子模板:

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
<span style="color: #0000ff;"><<span style="color: #800000;">h2<span style="color: #0000ff;">>{{ entry.title }}<span style="color: #0000ff;"></<span style="color: #800000;">h2<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">p<span style="color: #0000ff;">>{{ entry.body }}<span style="color: #0000ff;"></<span style="color: #800000;">p<span style="color: #0000ff;">><span style="color: #000000;">
{% endfor %}
{% endblock %}

extends标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。

那时,base.html中的三个block标签,并用子模版中的内容来替换这些block。根据blog_entries的值,子模板输出内容会是下面的内容

My amazing blog

<span style="color: #0000ff;"><<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">div <span style="color: #ff0000;">id<span style="color: #0000ff;">="sidebar"<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">ul<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">li<span style="color: #0000ff;">><<span style="color: #800000;">a <span style="color: #ff0000;">href<span style="color: #0000ff;">="/"<span style="color: #0000ff;">>Home<span style="color: #0000ff;"></<span style="color: #800000;">a<span style="color: #0000ff;">></<span style="color: #800000;">li<span style="color: #0000ff;">>
<span style="color: #0000ff;"><<span style="color: #800000;">li<span style="color: #0000ff;">><<span style="color: #800000;">a <span style="color: #ff0000;">href<span style="color: #0000ff;">="/blog/"<span style="color: #0000ff;">>Blog<span style="color: #0000ff;"></<span style="color: #800000;">a<span style="color: #0000ff;">></<span style="color: #800000;">li<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">ul<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">div<span style="color: #0000ff;">>

<span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;div </span><span style="color: #ff0000;"&gt;id</span><span style="color: #0000ff;"&gt;="content"</span><span style="color: #0000ff;"&gt;></span>
    <span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;h2</span><span style="color: #0000ff;"&gt;></span>Entry one<span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;h2</span><span style="color: #0000ff;"&gt;></span>
    <span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;p</span><span style="color: #0000ff;"&gt;></span>This is my first entry.<span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;p</span><span style="color: #0000ff;"&gt;></span>

    <span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;h2</span><span style="color: #0000ff;"&gt;></span>Entry two<span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;h2</span><span style="color: #0000ff;"&gt;></span>
    <span style="color: #0000ff;"&gt;<</span><span style="color: #800000;"&gt;p</span><span style="color: #0000ff;"&gt;></span>This is my second entry.<span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;p</span><span style="color: #0000ff;"&gt;></span>
<span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;div</span><span style="color: #0000ff;"&gt;></span>

<span style="color: #0000ff;"></<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>

请注意,子模版并没有定义sidebarblock,所以系统使用了父模版中的值。父模版的{% block %}标签中的内容总是被用作备选内容(fallback)

这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。

提示:

  • {% extends %}标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。

  • {% block %}标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。

  • 内容,那可能意味着你应该把内容移动到父模版中的一个{% block %}中。

  • 添加点其他的,而不是完全覆盖父模板的内容,那么你只需要在想要填充的块里,再加上一句{{ block.super }},我们就可以把父模板里的东西给留下来,如:

    即可。
  • {% endblock %}标签一个名字。例如:

    Highlighter sh-gutter">
    Highlighter_10180" class="SyntaxHighlighter python">

方法帮你清楚的看到哪一个 {% block %}标签关闭了。

block标签。这个限制的存在是因为block标签的作用是“双向”的。这个意思是,block标签不仅提供了一个坑去填,它还在 _父模版_中定义了填坑的内容。如果在一个模版中有两个名字一样的block标签,模版的父模版将不知道使用哪个block的内容

模板一般放在app下的templates中,Django会自动去这个文件夹中找。但 假如我们每个app的templates中都有一个 index.html,当我们在views.py中使用的时候,直接写一个 render(request,'index.html'),Django 能不能找到当前 app 的 templates 文件夹中的 index.html 文件夹呢?(答案是不一定能,有可能找错)

Django 模板查找机制:Django 查找模板的过程是在每个 app 的 templates 文件夹中找(而不只是当前 app 中的代码只在当前的 app 的 templates 文件夹中找)。各个 app 的 templates 形成一个文件夹列表,Django 遍历这个列表,一个个文件夹进行查找,当在某一个文件夹找到的时候就停止,所有的都遍历完了还找不到指定的模板的时候就是 Template Not Found (过程类似于Python找包)。这样设计有利当然也有弊,有利是的地方是一个app可以用另一个app的模板文件,弊是有可能会找错了。所以我们使用的时候在 templates 中建立一个 app 同名的文件夹,这样就好了。

这就需要把每个app中的 templates 文件夹中再建一个 app 的名称,仅和该app相关的模板放在 app/templates/app/ 目录下面,

例如:项目 zqxt 有两个 app,分别为 tutorial 和 tryit

<table class="SyntaxHighlighter plain" border="0" cellspacing="0" cellpadding="0">

这样,使用的时候,模板就是 "tutorial/index.html" 和 "tryit/index.html" 这样有app作为名称的一部分,就不会混淆。

模板语法之include

猜你在找的Django相关文章