您的位置:首页 > 编程语言 > Python开发

python下的web开发框架-Django,django模板的使用

2010-02-07 12:02 1321 查看
模板是简单的文本文件,它可以是html格式或是xml,csv等格式的

模板包括变量,括它会被值所替代当运行时,以及标签它控制模板的逻辑运算如if,else等
下面是一个简单的模板,我们将会对它做详细的说明

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
<a href="{{ story.get_absolute_url }}">
{{ story.headline|upper }}
</a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

变量
{{ variable }} 双括号里面的叫变量,当你前面如果存入一个变量的话,它将会用变量名所对应的值来替换双括号里面的值
使用 (.)来获得变量的属性(技术上当你在变量后输入.后它会依次去找对应的字典,属性,方法,列表index的值)
在上面的例子中。{{ section.title }}将会被section对象的title属性的值所替换

如果你使用的变量的不存在的话,模板系统将会插入''值也就是空值来做为默认值

模板过滤

你可以改变变量的显示方式如:全部大写,使用过滤

{{ name|lower }}就是一个简单的过滤,类似于linux操作系统的管道,它将会显示变量name的值,但是显示name的值之前经过lower这个过滤器,它将会把变量值转换成小写,我们使用|来提供一个过滤器

过滤可以以"链接",就是把一个变量经过过滤后的值再次过滤
如:{{ text|escape|linebreaks }} 就是输出text变量的值,然后转换为使用<p>的格式来显示 (需要验证是什么意思)

一些过滤要参数,如{{ bio|truncatewords:30 }},这个过滤器将会量示bio变量的前30个字符

过滤参数如果包含空格必须引用,如:{{ list|join:", " }},join一个列表使用,做为分隔附

django提供了三十个内置的过滤器,具体的就不一一说了,下面列几个常用的
例:
1.
{{ value|default:"nothing" }}
如果value的值没有提供或者为空,这时这个变量的值将会被设为nothing
2.
{{ value|length }}
返回value变量的长度,value可以为String或者是列表list
如:value值如为 ['a', 'b', 'c', 'd'],将会输出4
3.
{{ value|striptags }}
去掉html标签显示,如:如果你的value值为"<b>Joel</b> <button>is</button> a <span>slug</span>"
将会去掉html标签显示为:"Joel is a slug"

当然,我们也可以自己实现过滤器。

标签
{% tag %}类似于这样的就是标签,相对于变量,它复杂许多。它包括,创建文本输出,控制流程以及逻辑的以及引用外部资源(包部模板)

一些标签要求开始和结束标记,类似于html的<></>
{% tag %} ... tag contents ... {% endtag %}

Django有一大把的标签,下面我们列几个常用的给大家参考

for
迭代列表里面的每一个值,如:下面的列子,我们将输出每一个athletes列表里面的athlete的name属性
<ul>
{% for athlete in athlete_list %}
<li>{{ athlete.name }}</li>
{% endfor %}
</ul>
if and else
判断一个变量,如果变量的值为"true"则代码块或变量会被执行
如:
{% if athlete_list %}
Number of athletes: {{ athlete_list|length }}
{% else %}
No athletes.
{% endif %}
在上面的代码中,如果athlete_list的值不为空,将会执行 Number of athletes: {{ athlete_list|length }}代码,输出athlete_list的长度

ifequal and ifnotequal
显示内容,如果两个参数相同或不相同。如:

{% ifequal athlete.name coach.name %}
...
{% endifequal %}
如果
athlete.name的值和coach.name的值相同执行...处的代码
{% ifnotequal athlete.name "Joe" %}
...
{% endifnotequal %}
如果athlete.name的值不等于Joe,则执行下面的代码

block and extends
使用模板继承,一个非常好的重用模板的方式

当然,你可以自已写标签

注释

属于模板一部分的注释,使用{# #}
{# greeting #}hello
上面代码中,有用的只有hello.其他的为注释

模板继承

非常有用的功能,虽然有点复杂,它可以允许你先建立模板的骨架。然后一块一块的组合起来
下面我们用一个简单的例子来介绍模板继承

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>

<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>

在上面这个模板中,我们叫它为base.html.因为它定义了一个简单地的html页面纲要,我们只需要创建它的子模板去填充它空白的blocks内容即可

在这个模板中。我们空义了三块{% block %}标签,三块{% block %}标签我们可以使用它的子标签来填充它。我们需要子标签来覆盖它

下面我们写一个它的子标签:
{% extends "base.html" %}

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

{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

{% extends %} 标签告诉了我们该html的父模板为base.html
下面同样的block将会替换掉父标签中的内容,运行后,结果将会是:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My amazing blog</title>
</head>

<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>

<div id="content">
<h2>Entry one</h2>
<p>This is my first entry.</p>

<h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>

当然,如果子模板中没有定义变量的话,父模板会用它的内容来替代。

需要的话,模板也可以多重继承。下面是使用模板继承需要的一些心得:
1.创建base.html模板,它主要是存放模板的设计结构
2.创建base_SECTIONNAME.html板模,它继承base.html,它会包括页面的样式,设计
3.创建具体的模板,对于每一个要用到的页面,它继承base_SECTIONNAME.html,只需要存放要显示的变量就可以了

上面的方法可以最大程度的让代码可以重用,而且方面增加页面的内容
下面列一些注意点
1.如果你使用{% extends %}在模板中,必须是模板的第一个标签,否则,模板继承将会出错而不能工作

2.如果你的基础模板中有大量的{% block %}是好事,记住,子模板不需要定义所有的父定义过的blocks

3.如果你发现你的子模板中有重复的内容,也许意味着你将要移动你的{% block %}到父模板中去

4.如果你需要获得父模中block的内容,{{ block.super }} 变量不能使用,它仅仅是当你想覆盖父模板中相同块的内容.

5.为了增加可读性,block的名字一定要起有意义的

同一个模板中,不能有重复的{% block %}标签。

自动忽略html

当模板中生产html,会对显示变量的值生产一些影响
如:
Hello, {{ name }}.
如果我们在页面输入name变量的值为<script>alert('hello')</script>
这时模板发送的name值为Hello, <script>alert('hello')</script>
这时就会默认的调用js来弹出hello语句。。。。这是我们不希望看到的
还有。如果name包含'<'符号,如<b>username
结果将会显示:Hello, <b>username,这时输出的name值将会加粗。。
还有。一此恶意客户的攻击。对于这些情况。我们给出两点建议
1.确定每一个变量都经过escape 过滤器的过滤,它将会转换有害的html转为没害的。就是在django里面的标准解决方法。
2.你可以使用django定义的来代替一些值如
<转为<
>转为>
'转为'
"转为"
&转为&

如何关闭html过滤使用过滤器

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}
safe过滤器将会把html标签做为字符串来处理
显示时,如果输入;<b>
将会用如下形式:
This will be escaped: <b>

如何关闭html语法使用标签
{% autoescape off %}
Hello {{ name }}
{% endautoescape %}
autoescape将会关闭html语法显示.

String的自动转换:
{{ data|default:"3 < 2" }} 用第一种方法
{{ data|default:"3 < 2" }} 不好的方法。将会出错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: