文章目录
模板语法只有两种,变量用 {{ }},标签用{% %}。
变量
深度查询句点符
views文件
from django.shortcuts import render,HttpResponse
def index(request):
'''
模板语法只有两个:
变量: {{}}
1 深度查询 句点符
2 过滤器
标签: {% %}
'''
name="yuan"
i=1
l=[111,222,333]
info={"name":"yuan","age":22}
b=True
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
alex=Person("alex",35)
egon=Person("egon",33)
person_list=[alex,egon]
# return render(request,"index.html",{"n":name}) # 不必写那么多键值对
return render(request, "index.html", locals()) # 这个方法
index.html
<p>{{ n }}</p>
<p>{{ i }}</p>
<p>{{ info }}</p>
<p>{{ l }}</p>
<p>{{ alex }}</p>
<p>{{ person_list }}</p>
<p>{{ b }}</p>
<hr>
<h4>深度查询用句点符</h4>
<p>{{ l.1 }}</p>
<p>{{ info.name }}</p>
<p>{{ alex.name }}</p>
<p>{{ alex.age }}</p>
<p>{{ person_list.1.age }}</p>
过滤器
语法:
{{obj|filter__name:param}}
default
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default:"nothing" }}
length
返回值的长度。它对字符串和列表都起作用。例如:
{{ value|length }}
filesizeformat
将值格式化为一个 “人类可读的” 文件尺寸 (例如 ‘13 KB’, ‘4.1 MB’, ‘102 bytes’, 等等)
{{ value|filesizeformat }}
如果 value 是 123456789,输出将会是 117.7 MB。
date
如果 value=datetime.datetime.now()
{{ value|date:"Y-m-d" }}
slice
如果 value=“hello world”
{{ value|slice:"2:-1" }}
truncatechars
如果字符串字符多于指定的字符数量,那么会被截断。截断的字符串将以可翻译的省略号序列(“…”)结尾。
参数:要截断的字符数
{{ value|truncatechars:9 }}
truncatewords
按词组,不算标点符号,以空格。
value='你是 人 间 四月天'
value2='hello , world,iloveyou'
<p>{{ value|truncatechars:5 }}</p>
<p>{{ value2|truncatechars:5 }}</p>
<p>{{ value|truncatewords:3 }}
</p>
<p>{{ value2|truncatewords:3 }}</p>
结果:
你是...
he...
你是 人 间 ...
hello , world,iloveyou
safe
Django的模板中为了安全,会对HTML标签和JS等语法标签进行自动转义,为了在Django中关闭HTML的自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器“|safe”的方式告诉Django这段代码是安全的不必转义。比如:
value="<a href="">点击</a>"
{{ value|safe}}
add
value=[11,12]
{{value.0|add:10}}
uppper
value='hello'
{{value|uppper}}
等等,还可以自定义。
标签
for
语法:
views文件:
l=[111,222,333]
index.html:
{% for i in l %}
<p>{{ i }}</p>
{% endfor %}
{% for person in person_list %}
<p>{{ person.name }}</p>
{% endfor %}
可以利用{% for obj in list reversed %}反向完成循环。
遍历一个字典:
{% for key,val in dic.items %}
<p>{{ key }}:{{ val }}</p>
{% endfor %}
注:循环序号可以通过{{forloop}}显示
{% for person in person_list %}
<p>{{ forloop.counter0 }} {{ person.name }} , {{ person.age }}</p>
{% endfor %}
与for循环配合使用的有empty可选项目,如果没有元素可以遍历执行。
{% for person in person_list %}
<p>{{ forloop.counter0 }} {{ person.name }} , {{ person.age }}</p>
{% empty %}
<p>列表为空</p>
{% endfor %}
if标签
{% if %}会对一个变量求值,如果它的值是“True”(存在、不为空、且不是boolean类型的false值),对应的内容块会输出。
{% if num > 100 or num < 0 %}
<p>无效</p>
{% elif num > 80 and num < 100 %}
<p>优秀</p>
{% else %}
<p>凑活吧</p>
{% endif %}
{% if user %}
<p>
<a href="">hi {{ user }}</a>
<a href="">注销</a>
</p>
{% else %}
<p>
<a href=" ">登录</a>
<a href=" ">注册</a>
</p>
{% endif %}
with标签
缩短名字暂时替换
{% with person_list.1.name as n %}
{{ n }}
{% endwith %}
csrf_token
用于跨站请求伪造保护
form表单get请求获取页面,post请求传送数据,再次走试图函数。html在发送之前render方法将此标签渲染成隐藏的input标签,在浏览器检查下可以看到。这个input相当于这个通行证。
login.html:
<form action="" method="post">
{% csrf_token %}
<input type="text" name="user">
<input type="submit">
</form>
views文件
def login(request):
if request.method=="POST":
return HttpResponse("OK")
return render(request,"login.html")
自定义标签和过滤器
-
在settings,py文件INSTALLED_APPS配置添加应用。
-
在app中创建templatetags模块(模块名只能是templatetags),创建 任意.py 文件
3.文件内容:
from django import template # 固定的
register = template.Library() # 名字固定
@register.filter # 定义之后加过滤器
def multi_fliter(x, y): # 定义函数
return x * y
@register.simple_tag # 标签装饰器
def multi_tag(x, y):
return x * y
- 文件里调用
html文件调用方法:
<h4>自定义过滤器,标签</h4>
{#使用自定义过滤器,load 导入文件名#}
{% load my_tag_filter %}
<p>{{ i|multi_fliter:20 }}</p>
{#自定义过滤器 :i是第一个参数,20是第二个参数,所以最多两个参数#}
{#自定义标签,没有参数限制#}
<p>{% multi_tag 7 9 6 %}</p>
{#自定义过滤器可以逻辑判断, 自定义标签不行#}
{% if i|multi_fliter:10 > 100 %}
<p>100</p>
{% else %}
<p>{{ i }}</p>
{% endif %}
模板继承
解决html代码重用问题。
多个页面需要加载固定的部分,可以把固定的部分提出来单独写一个html文件,存放在模板文件夹templates里,需要用这个文件里的代码时直接调用。
{% include 'advertise.html' %}
如果多个文件基于一个模板文件的页面结构下扩展而来,可以把这个页面作为基础页面,在需要补充的部分留有空白block,新的文件可以继承这个基础页面,然后在block的地方填充自己所需的内容。
基础文件示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
{#block区留有空白,按需修改#}
{% block title %}
<title>base</title>
{% endblock %}
<!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
* {
margin: 0;
padding: 0;
}
.header {
width: 100%;
height: 50px;
background-color: #369;
}
</style>
</head>
<body>
<div class="header"></div>
<div class="container">
<div class="row">
<div class="col-md-3">
{# 加载所需要的部分#}
{% include 'advertise.html' %}
</div>
<div class="col-md-9">
{# block区填充自己所需部分#}
{% block con %}
<h4>content</h4>
{% endblock %}
</div>
</div>
</div>
</body>
</html>
继承页面示例:
{% extends 'base.html' %}
{% block title %}
<title>orders</title>
{% endblock %}
{% block con %}
{{ block.super }}
<h4>订单</h4>
{% endblock con%}
注意:
-
{% extends %} 标签,它必须是模版中的第一个标签。
-
base模版中 {% block %}标签越多越好。子模版不必定义全部父模版中的blocks,如果子模版没有定义,会采用父模板的blocks内的内容。
-
{{ block.super }},如果父模板的block区的内容还想用,可以用{{ block.super }},继承之后再补充自己的。
-
为了更好的可读性,给block起名
{% block content %}{% endblock content %} -
不能在一个模版中定义多个相同名字的 block 标签。