Django 模板语法

一、模板

只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板。

二、模板语法

模板语法变量:{{ }}

在Django模板中遍历复杂数据结构的关键是句点字符 .(其实就是点号)

views.py

from django.shortcuts import render

def index(request):
name = "Hello world!"
number = 101
lst = [1, 2, 3, 4, 5]
dic = {"name": "eric", "job": "teacher"} class People:
def __init__(self, name, age):
self.name = name
self.age = age def __str__(self):
return self.name + str(self.age) def dream(self):
return "你有梦想吗?" # 实例化
person_jack = People("jack", 10)
person_pony = People("pony", 36)
person_cent = People("cent", 55)
person_list = [person_jack, person_pony, person_cent] return render(request, "index.html",
{
"name": name,
"num": number,
"lst": lst,
"dic": dic, # 键对应的是模板里的名字,值对应的是上面定义的值
"person_jack": person_jack,
"person_pony": person_pony,
"person_list": person_list
}
)

templates/index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django 模板</title>
</head>
<body>
<h3>变量{{ variable }}:深度查询</h3>
<h5>{{ name }}</h5>
<p>{{ num }}</p>
<p>{{ lst }}</p>
<p>{{ dic }}</p>
<p>{{ lst.0 }}</p>
<p>{{ lst.4 }}</p>
<p>{{ dic.name }}</p>
<p>{{ dic.job}}</p>
<p>{{ person_jack.name }}</p>
<p>{{ person_jack.age }}</p>
<p>{{ person_list.2.name }}</p>
</body>
</html>

运行输出结果如下图所示:

注意:在使用templates时,需要在django项目的settings配置文件中对templates的路径做如下配:

TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# os.path.join(BASE_DIR, "templates"),启用django模板;
# 如果没有这句会出现"django.template.exceptions.TemplateDoesNotExist: index.html"错误
'DIRS': [os.path.join(BASE_DIR, "templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]

其中,局点符也可以用来引用对象的方法(无参数方法)

<h4>字典:{{ dic.name.upper }}</h4>

模板语法标签:{% tag %}

标签语法是:{% tag %},它比变量更加复杂:一些在输出中创建文本,一些通过循环或者逻辑来控制流程,一些加载其后的变量将使用道德额外信息到模板中。一些标签需要开始和结束标签(例如:{% tag %}... 标签内容...{% endtag %})。

1.for标签(循环序号可以通过{{ forloop }}显示)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django 模板</title>
</head>
<body>
<h3>循环取值</h3><hr>
{% for item in person_list %}
<p>{{ item.name }}, {{ item.age }}</p>
{% endfor %} <h3>循环取值:倒序</h3>
{% for item in person_list reversed %}
{# 序号从1开始 #}
<p>{{ forloop.counter }}---------->{{ item.name }}, {{ item.age }}</p>
{# 序号从0开始 #}
<p>{{ forloop.counter0 }}---------->{{ item.name }}, {{ item.age }}</p>
{# 序号倒序 #}
<p>{{ forloop.revcounter }}---------->{{ item.name }}, {{ item.age }}</p>
{% endfor %} <h3>循环取值:字典</h3>
{% for key, value in dic.items %}
<p>{{ key }}, {{ value }}</p>
{% endfor %}
</body>
</html>

运行结果如下图所示:

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

{% for person in person_list %}
<p>{{ person.name }}</p>
{% empty %}
<p>sorry,no this person</p>
{% endfor %}

3.if标签:{% if %}会对一个变量求值,如果它的值是"True"(存在、不为空且不是boolean类型的false值),对应的内容块被执行

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django 模板</title>
</head>
<body>
{% if num > 200 %}
<p>大于</p>
{% elif num == 200 %}
<p>等于</p>
{% else %}
<p>小于</p>
{% endif %} </body>
</html>

4.with:使用一个简单的名字还出一个复杂的变量,当我们需要一个"昂贵的"方法(比如:访问数据库)很多次的时候是非常有用的

{% with total=business.emlpoyees.count %}
{{ total }} empolyee {{ total | pluralize }}
% endwith %}
<p>{{ person_list.2.name }}</p>
{% with name=person_list.2.name %}
<p>{{ name }}</p>
{% endwith %}

5.csrf_token:跨站点请求伪造保护

提交数据的时候会做安全机制,当用户点击提交的时候会出现一个forbidden错误,就是用settings配置里面的csrf做的安全机制,如果我们不需要使用,可以将其注释。或者在form表单下面添加{% csrf_token %}来解决该问题(这才是真正的解决办法,注释不是解决办法)。

<h3>scrf_token</h3>
<form action="/tag/" method="post">
{% csrf_token %}
<p><input type="text" name="haiyan"></p>
<input type="submit">
</form>

模板语法过滤器:{{ obj|filter__name:param }},过滤器使用管道字符

1.default:{{ variable| default: "nothing"}},如果变量是false或者为空,使用默认值。否则,使用变量的值

<p>default过滤器:{{ li|default:"如果显示为空,设置解释性的内容。" }}</p>

2.length:返回值的长度,它对字符串和列表都起作用

{{ value | length }}        # 如果value是["a", "b", "c", "d"],那么输出是4

3.filesizeformat:将值格式化为"人类可读"的文件尺寸(例如:13KB,4.1M,102bytes等等)

{{ value | filesizeformat }}        # 如果value是123456789,输出将会是117.7MB

4.date:格式化日期时间格式

{{ value | date:"Y-m-d" }}        # 如果value=datetime.datetime.now(),返回时间的年-月-日格式

5.slice:切片

{{ value | slice:"2:-1" }}        # 如果value="hello world",返回'llo worl'

6.truncatechars:截断

如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(...)结尾,参数:要截断的字符数。

<p>截断字符: {{ content | truncatechars:20 }}</p>
<p>截断单词: {{ content | truncatewords:4 }}</p>

如果content是"i am is jack, where are you come from?"

输出结果:截断字符: i am is jack, whe...;截断单词i am is jack, where...

7.safe

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

value="<a href="">点击</a>""

{{ value | safe }}
<p>{{ label }}</p>        # 为了安全,系统会把标签变成字符串
<p>{{ label | safe }}</p> # 加上safe,确定数据时安全的才能被当成是标签

这里简单介绍常用的几个模板过滤器,更多内容请参考

三、自定义标签和过滤器

  • 1.在app目录中创建templatetags包(包名只能是templatetags);

  • 2.在项目settings.py中把templatetags目录作为app注册;
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'polls.apps.PollsConfig',
'polls.templatetags' # 作为app注册
]
  • 3.在customtags.py文件中添加自定义的标签和过滤器
from django import template

register = template.Library()       # register的名字是固定的,不可改变

@register.filter(name="cut")        # 过滤器在模板中使用时的name
def custom_cut(value, arg): # 将传递过来的参数arg替换为"#"
return value.repalce(arg, "#") @register.tag(name="current_time")
def current_time(parse, token): # parse解析器对象,token被解析的对象,包含标签的名字和格式化的格式
try:
tag_name, format_string = token.split_contents()
except:
raise template.TemplateSyntaxError("syntax")
return CurrentNode(format_string[1:-1]) # 传入模板中的节点类 import datetime class CurrentNode(template.Node):
def __init__(self, cus_format):
self.format_string = str(cus_format) def render(self, context):
now = datetime.datetime.now()
return now.strftime(self.format_string)
  • 4.编辑视图函数,把value传递给模板文件:
def index(request):
return render(request, "one.html", {"value": "hello world!"})
  • 5.在模板文件中使用的时候需要先导入customtags.py文件:
{% load customtags %}

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>自定义标签和过滤器</title>
</head>
<body>
{{ value|cut:"!" }}<br>
{% current_time "%Y-%m-%d %H:%M:%S" %}
</body>
</html>

注意:在模板中不要随意添加空格,尤其是变量和标签

运行结果为

Django 2.0 学习(12):Django 模板语法的更多相关文章

  1. Django 2.0 学习(07):Django 视图(进阶-续)

    接Django 2.0 学习(06):Django 视图(进阶),我们将聚焦在使用简单的表单进行处理和精简代码. 编写简单表单 我们将用下面的代码,来替换之前的detail模板("polls ...

  2. Django 2.0 学习(13):Django模板继承和静态文件

    Django模板继承和静态文件 模板继承(extend) Django模板引擎中最强大也是最复杂的部分就是模板继承了,模板继承可以让我们创建一个基本的"骨架"模板,它可以包含网页中 ...

  3. Django框架之第三篇模板语法(重要!!!)

    一.什么是模板? 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法分类 一.模板语法之变量:语法为 {{ }}: 在 Django 模板中遍历复杂数据结构的关键 ...

  4. Django框架之第三篇模板语法

    一.什么是模板? 只要是在html里面有模板语法就不是html文件了,这样的文件就叫做模板. 二.模板语法分类 一.模板语法之变量:语法为 {{ }}: 在 Django 模板中遍历复杂数据结构的关键 ...

  5. Django 2.0 学习(08):Django 自动化测试

    编写我们的第一个测试 确定bug 幸运的是,在polls应用中存在一个小小的bug急需修复:无论Question的发布日期是最近(最后)的日期,还是将来很多天的日期,Question.was_publ ...

  6. Django 2.0 学习(06):Django 视图(进阶)

    概述 Django中的特方法,该方法代表了Django的Web页面,并且视图具有特定的模板.以博客应用为例进行说明,在博客应用中应该包含下面的视图: 博客主页:显示最近的一些记录: 详细页面:单个详细 ...

  7. Django 2.0 学习(04):Django数据库

    数据库设置/配置 打开mysite/settings.py,我们会发现Django是用的是默认的数据库SQLite,如下图所示: Django也是支持其它数据库的,比如PostgreSQL.MySQL ...

  8. Django 2.0 学习(19):Django 分页器

    Django 分页器 要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器) views.py from django.shortcuts im ...

  9. django 学习-12 Django表单 初步

    1.先创建项目和应用 django.admin.py    startproject   cs cd cs django.admin.py   startapp   blog 2.vim  setti ...

随机推荐

  1. python之attrgetter函数对对象排序

    # 使用attrgetter函数对对象排序 # attrgetter处理对象,itemgetter处理序列 from operator import attrgetter class user(): ...

  2. BZOJ4259 残缺的字符串(FFT)

    两个串匹配时相匹配的位置位置差是相同的,那么翻转一个串就变成位置和相同,卷积的形式. 考虑如何使用卷积体现两个位置能否匹配.一个暴力的思路是每次只考虑一种字符,将其在一个串中设为1,并在另一个串中将不 ...

  3. 【BZOJ3551】【BZOJ3545】 【ONTAK2010】 Peaks (kruskal重构树+主席树)

    Description ​ 在\(Bytemountains\)有\(~n~\)座山峰,每座山峰有他的高度\(~h_i~\). 有些山峰之间有双向道路相连,共\(~m~\)条路径,每条路径有一个困难值 ...

  4. 实现 60fps 的网易云音乐首页

    网易云音乐是一款很优秀的音乐软件,我也是它的忠实用户.最近在研究如何更好的开发TableView,接着我写了一个Model驱动的小框架 - MDTable.为了去验证框架的可用性,我选择了网易云音乐的 ...

  5. 树莓派上使用KickThemOut对局域网内的设备进行ARP欺骗

    安装KickThemOut工具 $ git clone https://github.com/k4m4/kickthemout.git $ cd kickthemout/ $ sudo -H pip ...

  6. A1038. Recover the Smallest Number

    Given a collection of number segments, you are supposed to recover the smallest number from them. Fo ...

  7. java NIO 直接与非直接缓冲区

    ByteBuffer有两个创建缓冲区的方法:static ByteBuffer allocate(int capacity)static ByteBuffer allocateDirect(int c ...

  8. css实现单选效果,看看有趣的tabIndex

    以前我实现单选变色几乎都是用js实现的,今天看到有个css属性可以直接实现单选变色,很开心啊~ 话不多说看效果 实现的代码如下 下面我们看看用focus实现别的有趣的效果 话不多说看效果 实现的代码如 ...

  9. JS模板引擎handlebars.js的简单使用

    handlebars.js的使用 首先我们要明白handlebars.js是干什么用的,我们知道使用jsp很麻烦, 于是我们开始使用freemarker等模板引擎,但这个只是针对服务器端来解 析的,那 ...

  10. CF786B Legacy && 线段树优化连边

    线段树优化连边 要求点 \(x\) 向区间 \([L, R]\) 连边, 一次的复杂度上限为 \(O(n)\) 然后弄成线段树的结构 先父子连边边权为 \(0\) 这样连边就只需要连父亲就可以等效于连 ...