在for循环中,DTL提供了一些变量可供使用。
forloop.counter: 当前循环的下标。以1作为起始值。
forloop.counter0: 当前循环的下标。以0作为起始值。
forloop.revcounter: 当前循环的反向下标值。比如列表有5个元素,那么第一次遍历这个属性是等于5,第二次是4,以此类推。并且是以1作为最后一个元素的下标。
forloop.revcounter0: 类似于forloop.revcounter。不同的是最后一个元素的下标是从0开始。
forloop.first: 是否是第一次遍历。
forloop.last: 是否是最后一次遍历。
forloop.parentloop: 如果有多个循环嵌套,那么这个属性代表的是上一级的for循环。
for…in…empty标签:这个标签使用跟for…in…是一样的,只不过是在遍历的对象如果没有元素的情况下,会执行empty中的内容。
{% for person in persons %}
<li>{{ person }}li>
{% empty %}
暂时还没有任何人
{% endfor %}
注意:在for循环中,break,continue语句是用不了的。
url标签:在模版中,我们经常要写一些url,比如某个a标签中需要定义href属性。当然如果通过硬编码的方式直接将这个url写死在里面也是可以的。但是这样对于以后项目维护可能不是一件好事。因此建议使用这种反转的方式来实现,类似于django中的reverse一样。
<a href="{% url 'book:list' %}">图书列表页面a>
如果url反转的时候需要传递参数,那么可以在后面传递。但是参数分位置参数和关键字参数。位置参数和关键字参数不能同时使用。
# path部分
path('detail//' ,views.book_detail,name='detail')
# url反转,使用位置参数
<a href="{% url 'book:detail' 1 %}">图书详情页面</a>
# url反转,使用关键字参数
<a href="{% url 'book:detail' book_id=1 %}">图书详情页面</a>
如果想要在使用url标签反转的时候要传递查询字符串的参数,那么必须要手动在在后面添加。
<a href="{% url 'book:detail' book_id=1 %}?page=1">图书详情页面a>
如果需要传递多个参数,那么通过空格的方式进行分隔。
<a href="{% url 'book:detail' book_id=1 page=2 %}">图书详情页面a>
with标签
{% with name=person.0 %}
{{ name }}
{% endwith %}
{% with person.0 as name %}
{{ name }}
{% endwith %}
autoescape 自动转义标签
视图文件:book/views.py,传递参数到前端页面进行渲染:
def book_detail(request):
context = {
"username": "12345",
"book": ["python", "java", "php"],
"books": ("python", "java", "php"),
"info": {
"name": "xxxxx",
"url": "百度", # 链接渲染到前端会因为源码中的render_to_string方法变成字符串
},
# 传递类
"person": Person("ch")
}
# 注意第一个参数request要有 # render在源码中封装了render_to_string和HttpResponse
return render(request, "book_detail.html", context=context)
前端页面渲染book_detail.html:
{{info.url}}
{% autoescape off %}}
{{info.url}}
{% endautoescape %}}
更多标签 : https://docs.djangoproject.com/en/2.0/ref/templates/builtins/
在模版中,有时候需要对一些数据进行处理以后才能使用。一般在Python中我们是通过函数的形式来完成的。而在模版中,则是通过过滤器来实现的。过滤器使用的是|来使用。
将传进来的参数添加到原来的值上面。这个过滤器会尝试将值和参数转换成整形然后进行相加。如果转换成整形过程中失败了,那么会将值和参数进行拼接。如果是字符串,那么会拼接成字符串,如果是列表,那么会拼接成一个列表。
{{ value|add:"2" }}
如果value是等于4,那么结果将是6。如果value是等于一个普通的字符串,比如abc,那么结果将是abc2。
实例如下:
from django.shortcuts import render
from django.template import defaultfilters
def index(request):
context = {
"num": 2,
"str": 'abc',
}
return render(request, 'index.html', context=context)
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
<h1>测试h1>
<p> 首页p>
<p>{{ num|add:"1" }}p>
<p>{{ str|add:"1" }}p>
<p>{{ str|add:"xxxxx" }}p>
body>
html>
移除值中所有指定的字符串。类似于python中的replace(args,"")。
{{ value|cut:" " }}
将一个日期按照指定的格式,格式化成字符串。
# 数据
context = {
"birthday": datetime.now()
}
# 模版
{{ birthday|date:"Y/m/d" }}
<p>{{ birthday }}p>
<p>{{ birthday|date:"Y/m/d" }}p>
<p>{{ birthday|date:"Y/m/d H:i:s" }}p>
如果值被评估为False。比如[],"",None,{}等这些在if判断中为False的值,都会使用default过滤器提供的默认值。
{{ value|default:"nothing" }}
如果value是等于一个空的字符串。比如"",那么以上代码将会输出nothing。
<p>{{ info|default:"暂时没有设置签名" }}p>
上面代码中info如果有值,会显示views.py中传输过来的值,如果没有,会显示default:“暂时没有设置签名”。
返回列表/元组/字符串中的第一个元素。
{{ value|first }}
返回列表/元组/字符串中的最后一个元素。
{{ value|last }}
def index(request):
context = {
"num": 2,
"str": 'abc',
"birthday": datetime.now(),
"info": "个性签名",
"l1": [1, 2, 3, 4, 5, 6, 7, 8],
"z1": ("1", "2", "3", "4"),
}
return render(request, 'index.html', context=context)
index.html文件中渲染:
<p>{{ l1|first }}</p>
<p>{{ l1|last }}</p>
<p>{{ z1|first }}</p>
<p>{{ z1|last }}</p>
使用四舍五入的方式格式化一个浮点类型。如果这个过滤器没有传递任何参数。那么只会在小数点后保留一个小数,如果小数后面全是0,那么只会保留整数。当然也可以传递一个参数,标识具体要保留几个小数。
<ul>
<li>{{ 34.32|floatformat }}li>
<li>{{ 34.35|floatformat }}li>
<li>{{ 34.353333|floatformat:3}}li>
ul>
类似与Python中的join,将列表/元组/字符串用指定的字符进行拼接.
{{ value|join:"/" }}
如果value是等于[‘a’,‘b’,‘c’],那么以上代码将输出a/b/c。
获取一个列表/元组/字符串/字典的长度。
{{ value|length }}
如果value是等于[‘a’,‘b’,‘c’],那么以上代码将输出3。如果value为None,那么以上将返回0。
将值中所有的字符全部转换成小写。
{{ value|lower }}
类似于lower,只不过是将指定的字符串全部转换成大写。
在被给的列表/字符串/元组中随机的选择一个值。
{{ value|random }}
标记一个字符串是安全的。也即会关掉这个字符串的自动转义。
{{value|safe}}
如果value是一个不包含任何特殊字符的字符串,比如这种,那么以上代码就会把字符串正常的输入。如果value是一串html代码,那么以上代码将会把这个html代码渲染到浏览器中。
类似于Python中的切片操作。
{{ some_list|slice:"2:" }} 从第2个元素到最后的元素
删除字符串中所有的html标签。
{{ value|striptags }}
如果给定的字符串长度超过了过滤器指定的长度。那么就会进行切割,并且会拼接三个点来作为省略号。
{{ value|truncatechars:5 }}
更多可以查看Django源码
from django.template import defaultfilters,defaulttags
有时候一些代码是在许多模版中都用到的。如果我们每次都重复的去拷贝代码那肯定不符合项目的规范。一般我们可以把这些重复性的代码抽取出来,就类似于Python中的函数一样,以后想要使用这些代码的时候,就通过include包含进来。这个标签就是include。
# header.html
<p>我是headerp>
# footer.html
<p>我是footerp>
# main.html
{% include 'header.html' %}
<p>我是main内容p>
{% include 'footer.html' %}
include标签寻找路径的方式。也是跟render渲染模板的函数是一样的。
默认include标签包含模版,会自动的使用主模版中的上下文,也即可以自动的使用主模版中的变量。如果想传入一些其他的参数,那么可以使用with语句。
# header.html
<p>用户名:{{ username }}p>
# main.html
{% include "header.html" with username='xxx' %}
在前端页面开发中。有些代码是需要重复使用的。这种情况可以使用include标签来实现。也可以使用另外一个比较强大的方式来实现,那就是模版继承。模版继承类似于Python中的类,在父类中可以先定义好一些变量和方法,然后在子类中实现。模版继承也可以在父模版中先定义好一些子模版需要用到的代码,然后子模版直接继承就可以了。并且因为子模版肯定有自己的不同代码,因此可以在父模版中定义一个block接口,然后子模版再去实现。
{% load static %}
<html lang="en">
<head>
<link rel="stylesheet" href="{% static 'style.css' %}" />
<title>{% block title %}
我的站点
{% endblock %}title>
head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">首页a>li>
<li><a href="/blog/">博客a>li>
ul>
{% endblock %}
div>
<div id="content">
{% block content %}
{% endblock %}
div>
body>
html>
这个是父模版,我们取名叫做base.html,定义好一个简单的html骨架,然后定义好两个block接口,让子模版来根据具体需求来实现。子模板然后通过extends标签来实现.
{% extends "base.html" %}
{% block title %}
博客列表
{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}h2>
<p>{{ entry.body }}p>
{% endfor %}
{% endblock %}
在一个网页中,不仅仅只有一个html骨架,还需要css样式文件,js执行文件以及一些图片等。因此在DTL中加载静态文件是一个必须要解决的问题。在DTL中,使用static标签来加载静态文件。要使用static标签,首先需要{% load static %}。
步骤如下:
默认添加了django.contrib.staticfiles
默认创建了STATIC_URL
创建static文件夹:
注意:为什么在app下创建一个static文件夹,还需要在这个static下创建一个同app名字的文件夹呢?
原因是如果直接把静态文件放在static文件夹下,那么在模版加载静态文件的时候就是使用logo.jpg,如果在多个app之间有同名的静态文件,这时候可能就会产生混淆。而在static文件夹下加了一个同名app文件夹,在模版中加载的时候就是使用app/logo.jpg,这样就可以避免产生混淆。
settings.py
# 指定静态文件目录
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static")
]
{% load static %}
<link rel="stylesheet" href="{% static 'style.css' %}">
settings.py
中的TEMPLATES/OPTIONS
添加'builtins':['django.templatetags.static']
,这样以后在模版中就可以直接使用static标签,而不用手动的load了。settings.py:这样设置会在加载静态资源文件的路径前加上/static/
路径
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], # 模板路径设置
'APP_DIRS': True,
'OPTIONS': {
# 不想每次在模版中加载静态文件都使用load加载static标签,以后在模版中就可以直接使用static标签,而不用手动的load了
'builtins':['django.templatetags.static'],
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
这样在模版中就可以直接使用static标签,而不用手动的load了
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
<link rel="stylesheet" href="{% static 'index.css' %}">
head>