一、模板支持的语法

Django模板中只需要记两种特殊符号:

{{ }}表示变量,在模板渲染的时候替换成值
{% %}表示逻辑相关的操作。

二、 变量(使用双大括号来引用变量)

1、语法格式:{{var_name}}

变量名由字母数字和下划线组成。

例子

urls.py文件指定url和views中的函数对应关系
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^time/$', views.localtime),
] views.py文件中编写函数,指定页面并传递字典参数
from django.shortcuts import render, HttpResponse
import datetime def localtime(request):
time = datetime.datetime.now()
return render(request, 'time.html', {'time':time}) time.html编写html页面,通过双大括号接收字典参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{{ time }}
</body>
</html> 访问http://127.0.0.1:8000/time/显示时间
Feb. 15, 2019, 1:53 p.m.

locals()可以将函数中所有的变量全部传递给模板,可能会造成传递了多余的参数。

def test(request):
a = 1
b = 2
c = 3
return render(request, 'test.html', locals()) #可以将a,b,c全部传递给模板

2、 深度变量的查找(万能的句点号)

上面例子中,我们传递的参数值主要是字符串,然而模板系统能够非常简洁地处理更加复杂的数据结构,例如list、dictionary和自定义的对象。在Django模板中遍历复杂数据结构的关键是句点字符 (.)。

urls.py和views.py中的代码不变,time.html文件修改如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>日期:{{ time.year }}年{{ time.month }}月{{ time.day }}日</p>
</body>
</html> 访问网页显示如下:
日期:2019年2月15日

例子2:循环显示列表中的内容

views.py
def people(request):
people = [
{'name':'tom', 'age':20},
{'name':'mike', 'age':21},
{'name':'jack', 'age':22},
]
return render(request, 'people.html', {'people':people}) people.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
table{
border: 1px solid black;
border-spacing: 0;
width: 300px;
}
table td{
border:1px solid;
text-align: center;
padding: 10px 0px;
}
</style>
</head>
<body>
<table>
<tr>
<td>ID</td>
<td>姓名</td>
<td>年龄</td>
</tr>
{% for people in people %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ people.name }}</td>
<td>{{ people.age }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
访问页面结果显示:

例子3:

def template_test(request):
l = [11, 22, 33]
d = {"name": "alex"} class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age def dream(self):
return "{} is dream...".format(self.name) Alex = Person(name="Alex", age=34)
Egon = Person(name="Egon", age=9000)
Eva_J = Person(name="Eva_J", age=18) person_list = [Alex, Egon, Eva_J]
return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list})

模板中支持的写法:

{# 取l中的第一个参数 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取对象的name属性 #}
{{ person_list.0.name }}
{# .操作只能调用不带参数的方法 #}
{{ person_list.0.dream }}

注:当模板系统遇到一个(.)时,会按照如下的顺序去查询:

  • 在字典中查询
  • 属性或者方法
  • 数字索引

3 变量的过滤器(filter)的使用

语法格式:{{obj|filter:param}}
'|'左右没有空格

value1 = 'abc'
value2 = 11
value3 = []
value4 = None
value5 = 'name is tom and age is 20'
value6 = '姓名小明年龄20'
value7 = '<a herf="#">跳转</a>'
value8 = 'https://www.baidu.com/?a=1&b=2' <p>日期:{{ time.year}}年{{ time.month}}月{{ time.day}}日</p>
#日期:2019年2月15日 格式化日期
<p>日期:{{ time|date:"Y年m月d日" }}</p>
#日期:2019年02月15日 <p>日期:{{ time|date:"Y-m" }}</p>
#日期:2019-02 字母大写
<p>{{ value1|upper }}</p>
#ABC 变量值加2,如果变量是float则只显示整数部分
<p>{{ value2|add:2 }}</p>
# 首字母大写
<p>{{ value1|capfirst }}</p>
#Abc title标题
{{ value|title }} ljust左对齐
{{ value|ljust:"" }} rjust右对齐
{{ value|rjust:"" }} center居中
{{ value|center:"" }} join使用字符串拼接列表。同python的str.join(list)。
{{ value |join:" // " }} 切除掉指定字符串,可以用于切掉空格
<p>{{ value1 | cut:'b' }}</p>
#ac 如果值为false,则显示默认值
<p>{{ value3 | default:'值是假或空' }}</p>
#值是假或空 如果值为None,则显示默认值
<p>{{ value4 | default_if_none:'值是None' }}</p>
#值是None 只显示前3个单词,以空格为分隔,后面的内容显示为...
<p>{{ value5 | truncatewords:3 }}</p>
#name is tom ... 只显示前10个字符,后面的内容显示为...,而且这10个字符包括3个点,也就是只显示前7个字符
<p>{{ vlaue6 | truncatechars:7 }}</p> <p>{{ value7 }}</p>
#<a herf="#">跳转</a> <p>去掉自动转义:
{% autoescape off %}
{{ value7 }}
{% endautoescape %}
</p>
#跳转 <p>{{ value7 | safe }}</p>
#跳转 <p>{{ value7 | striptags }}</p>
#跳转 转成KB格式
<p>{{ value2 | filesizeformat }}</p>
#11 bytes <p>第1个字符:{{ value1 | first }}</p>
#a <p>最后1个字符:{{ value1 | last }}</p>
#c <p>显示长度:{{ value1 | length }}</p>
# <p>切片:{{ value1 | slice:'1::' }}</p>
#bc <p>{{ value8 | urlencode }}</p>
#https%3A//www.baidu.com/%3Fa%3D1%26b%3D2

三、 标签(tag)的使用(使用大括号和百分号的组合来表示tag)

语法格式: {% tags %}

1、 if elif和else的使用

if语句支持 and 、or、==、>、<、!=、<=、>=、in、not in、is、is not判断。

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

{% if num >= 100 %}
{% if num > 200 %}
<p>num大于200</p>
{% else %}
<p>num大于100小于200</p>
{% endif %} {% elif num < 100%}
<p>num小于100</p> {% else %}
<p>num等于100</p> {% endif %}

{% if %} 标签接受and,or或者not来测试多个变量值或者否定一个给定的变量
{% if %} 标签不允许同一标签里同时出现and和or,否则逻辑容易产生歧义,例如下面的标签是不合法的:{% if obj1 and obj2 or obj3 %}

2、 for的使用

{% for %}标签允许你按顺序遍历一个序列中的各个元素,每次循环模板系统都会渲染{% for %}和{% endfor %}之间的所有内容。

<ul>
{% for obj in list %}
<li>{{ obj.name }}</li>
{% endfor %}
</ul>

在标签里添加reversed来反序循环列表:

{% for obj in 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 %}

系统不支持中断循环,系统也不支持continue语句,{% for %}标签内置了一个forloop模板变量,这个变量含有一些属性可以提供给你一些关于循环的信息

1、forloop.counter表示循环的次数,它从1开始计数,第一次循环设为1:

{% for item in todo_list %}
<p>{{ forloop.counter }}: {{ item }}</p>
{% endfor %}

2、forloop.counter0 类似于forloop.counter,但它是从0开始计数,第一次循环设为0

3、forloop.revcounter 倒序排序,最小为1

4、forloop.revcounter0 倒序排序,最小为0

5、forloop.first当第一次循环时值为True,在特别情况下很有用:

{% for object in objects %}
{% if forloop.first %}<li class="first">{% else %}<li>{% endif %}
{{ object }}
</li>
{% endfor %}

6、forloop.last 当前循环是不是最后一次循环(布尔值)

7、forloop.parentloop 本层循环的外层循环

# 富有魔力的forloop变量只能在循环中得到,当模板解析器到达{% endfor %}时forloop就消失了
# 如果你的模板context已经包含一个叫forloop的变量,Django会用{% for %}标签替代它
# 在其他非循环的地方,你的forloop变量仍然可用

3、 empty的使用

{% empty %}不需要写{% endempty %}

<ul>
{% for user in user_list %}
<li>{{ user.name }}</li>
{% empty %}
<li>空空如也</li>
{% endfor %}
</ul>

4、 with

定义一个中间变量,用更简单的变量名替代复杂的变量名

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} {{ total }} {% endwith %}

5、 csrf_token标签

用于生成csrf_token的标签,用于防治跨站攻击验证。 其实,这里是会生成一个input标签,和其他表单标签一起提交给后台的。

6、 url

引用路由配置的地址别名

<form action="{% url "bieming"%}" >
{%csrf_token%}
<input type="text">
<input type="submit"value="提交">
</form>

7、 verbatim

禁止render

{% verbatim %}
{{ hello }}
{% endverbatim %}

8、 注释

{# ... #}

9、 注意事项

1). Django的模板语言不支持连续判断,即不支持以下写法:

{% if a > b > c %}
...
{% endif %}

2). Django的模板语言中属性的优先级大于方法

def xx(request):
d = {"a": 1, "b": 2, "c": 3, "items": "100"}
return render(request, "xx.html", {"data": d})

如上,我们在使用render方法渲染一个页面的时候,传的字典d有一个key是items,并且还有默认的 d.items() 方法,此时在模板语言中:
{{ data.items }}默认会取d的items key的值100。

四、extend模板继承

到目前为止,我们的模板范例都只是些零星的 HTML 片段,但在实际应用中,你将用Django模板系统来创建整个HTML页面。 这就带来一个常见的Web开发问题:在整个网站中,如何减少共用页面区域(比如站点导航)所引起的重复和冗余代码?Django解决此类问题的首选方法是使用一种优雅的策略—— 模板继承 。

本质上,模板继承就是先构造一个基础框架模板,而后在其子模板中对它所包含站点公用部分和定义块进行重载。

1、定义基础模板

该模板将由子模板所继承,以下是基础模板base.html:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>欢迎访问</h1>
{% block content %}{% endblock %} {% block footer %}
<hr>
<p>Thanks for visit my site</p>
{% endblock %}
</body>
</html>

使用模板标签: {% block %} 。 所有的 {% block %} 标签告诉模板引擎,子模板可以重载这些部分。 每个{% block %}标签所要做的是告诉模板引擎,该模板下的这一块内容将有可能被子模板覆盖。

2、继承母板

现在我们已经有了一个基本模板,我们可以通过多个子模板模板来继承它,子页面中在页面最上方使用{% extends 'base.html' %}语法来继承母板

user.html
{% extends "base.html" %}
{% block title %}user{% endblock %}
{% block content %}
<p>用户管理界面</p>
{% endblock %} host.html
{% extends "base.html" %}
{% block title %}host{% endblock %}
{% block content %}
<p>主机管理界面</p>
{% endblock %}

如果想进行站点级的设计修改,仅需修改 base.html ,所有其它模板会立即反映出所作修改。

3、块(block)

通过在母板中使用{% block xxx %}来定义"块"。
在子页面中通过定义母板中的block名来对应替换母板中相应的内容。

{% block page-main %}
<p>世情薄</p>
<p>人情恶</p>
<p>雨送黄昏花易落</p>
{% endblock %}

4、组件
可以将常用的页面内容如导航条,页尾信息等组件保存在单独的文件中,然后在需要使用的地方按如下语法导入即可。

{% include 'navbar.html' %}

以下是其工作方式:

1、在加载user.html和host.html模板时,模板引擎发现了 {% extends %} 标签, 注意到该模板是一个子模板。
2、模板引擎立即装载其父模板,即base.html。此时,base.html中的三个{% block %}标签中的内容将使用子模板的内容替换这些block。
3、由于子模板并没有定义footer块,模板系统将使用在父模板中定义的值。

使用继承的一种常见方式是下面的三层法:

<1> 创建base.html模板,在其中定义站点的主要外观,这些都是不常修改甚至从不修改的部分。
<2> 为网站的每个区域创建base_SECTION.html模板(例如, base_photos.html 和 base_form.html )。这些模板对base.html进行拓展,并包含区域特定的风格与设计。
<3> 为每种类型的页面创建独立的模板,例如论坛页面或者图片库。 这些模板拓展相应的区域模板。
这个方法可最大限度地重用代码,并使得向公共区域(如区域级的导航)添加内容成为一件轻松的工作。

以下是使用模板继承的一些诀窍:

<1>如果在模板中使用 {% extends %} ,必须保证其为模板中的第一个模板标记。 否则,模板继承将不起作用。
<2>一般来说,基础模板中的 {% block %} 标签越多越好。 记住,子模板不必定义父模板中所有的代码块,因此你可以用合理的缺省值对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。 俗话说,钩子越多越好。
<3>如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个 {% block %} 中。
如果你需要访问父模板中的块的内容,使用 {{ block.super }}这个标签吧,这一个魔法变量将会表现出父模板中的内容。 如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。
<4>不允许在同一个模板中定义多个同名的 {% block %} 。 存在这样的限制是因为block标签的工作方式是双向的。
也就是说,block 标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的 {% block %} 标签,父模板将无从得知要使用哪个块的内容。

五、静态文件相关

settings.py文件:

STATIC_URL = '/static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'statics'),
]

将images文件夹、mytest.js等静态文件放到创建的statics文件夹中

模板文件:

{% load static %}
<img src="{% static 'images/hi.jpg' %}" alt="Hi!" /> 引用JS文件时使用:
{% load static %}
<script src="{% static 'mytest.js' %}"></script> 某个文件多处被用到可以存为一个变量
{% load static %}
{% static "images/hi.jpg" as myphoto %}
<img src="{{ myphoto }}"></img>

Django04-模板系统Template的更多相关文章

  1. Django 模板系统(template)

    介绍 官方文档 常用模板语法 只需要记两种特殊符号: {{  }} 和  {% %} 变量相关的用{{}} 逻辑相关的用{%%} 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模 ...

  2. django基础2: 路由配置系统,URLconf的正则字符串参数,命名空间模式,View(视图),Request对象,Response对象,JsonResponse对象,Template模板系统

    Django基础二 request request这个参数1. 封装了所有跟请求相关的数据,是一个对象 2. 目前我们学过1. request.method GET,POST ...2. reques ...

  3. python学习笔记--Django入门二 Django 的模板系统

    为了使网站更干净简洁更容易维护,页面的设计和Python的代码必须分离开.我们可以使用Django的 模板系统 (Template System)来实现这种模式. 几个简单的模板标签(tag):   ...

  4. 第四章:Django 的模板系统(转)

    在之前的章节中,你可能觉得例子中视图返回文本有点不妥.即是, HTML 是直接写在 Python 代码中的.     这种做法会导致这些问题:     要做任何设计上的更改就必须改写 Python 代 ...

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

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

  6. 模板层template

    继续之前的views,你可 能已经注意到我们例子中视图中返回的的方式有点特别.也就是说.HTML被直接硬编码在Python代码之中 def current_datetime(request): now ...

  7. dj 模板层template

    1 模板语法之变量 在 Django 模板中遍历复杂数据结构的关键是句点字符, 语法: {{var_name}} def index(request): import datetime s=" ...

  8. Django-04模板层

    你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. def current_datetime(request): now = datet ...

  9. Django框架-模板系统

    来看一段代码 def current_datetime(request): now = datetime.datetime.now() html = "<html><bod ...

  10. Django基础——模板层(template) (Day67)

    阅读目录 变量 标签 自定义过滤器和标签 模板层(template) 你可能已经注意到我们在例子视图中返回文本的方式有点特别. 也就是说,HTML被直接硬编码在 Python代码之中. 1 2 3 4 ...

随机推荐

  1. java基础-arrayList

      ArrayList: 结构之钱了解了,ArrayList()会构造出一个初始容量=10的空的列表: ArrayList()的增加和删除都是拷贝数组到新的数组(如果当前数组容量不足的话),把数组内的 ...

  2. 第六节《Git克隆》

    本节学习如何使用git clone命令建立版本库克隆,以及如何使用git push和gitpull命令实现克隆之间的同步. Git的版本库目录和工作区在一起,因此存在一损俱损的问题,即如果删除一个项目 ...

  3. 批量写入redis

    批量写入redis key := GetSeriesKey(series.Id) idNames = append(idNames, key, series.Name) == { err = Mset ...

  4. Java高级特性 第9节 Socket机制

    一.Socket简介 1.Socket概述 Java最初是作为网络编程语言出现的,它对网络的高度支持,使得客户端和服务器流畅的沟通变成现实.而在网络编程中,使用最多的就是Socket,每一个实用的网络 ...

  5. spring 普通类注入为null,通过自定义SpringUtils解决

    package com.jathams.spring; import org.springframework.beans.BeansException; import org.springframew ...

  6. 解决Tomcat的IllegalArgumentException: Control character in cookie value or attribute错误

    接口中带有中文,tomcat8 17-Apr-2019 13:21:23.734 严重 [http-nio-8082-exec-2] org.apache.coyote.http11.Abstract ...

  7. 安装Visual Studio 语言包时出现windows 程序兼容模式已打开.请将其关闭

    打开 cmd.exe 输入 安装包路径 /Uninstall例如:D:\vs_lang_cn.exe /Uninstall (中间有个空格,Uninstall前是个左斜杠)回车 后 安装包会运行.点击 ...

  8. redis 缓存击穿 看一篇成高手系列3

    什么是缓存击穿 在谈论缓存击穿之前,我们先来回忆下从缓存中加载数据的逻辑,如下图所示 因此,如果黑客每次故意查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查询,这样缓存就失去了意义.如果 ...

  9. 2019年3月更新 技术分享 WPF基本界面制作

    1.制作流程1.在vs中建立一个wpf程序2.建立一个主页面(.cs)(注:C#程序每一个页面都由两个文件构成一个xaml一个cs,一个前端文件一个后台文件)3.在主页面中添加按钮,按钮中嵌入图片,这 ...

  10. abaqus 帮助文档 Substructure(子结构) 理论

    对于静态问题,可以缩减到只保留Retain Node的刚度矩阵和载荷矩阵: 但对于动力问题,还需要增加内部节点作为retain node,但这样会有点麻烦,更为常用的方式是保留子结构的模态和振型.