模板语言
什么是模板语言?
html+逻辑控制语句
Template和Context
在终端:python manage.py shell 进入django 环境
>>> from django.template import Context,Template
>>> t = Template('My name is {{name}}')
>>> c= Context({'name':'kkk'})
>>> t.render(c)
'My name is kkk'
简而言之就是{{ 变量 }} 嵌套在html中 变量可以直接从后端获取
深度变量的查找–> 万能的句点号.
最好是用几个例子来说明一下。
# 首先,句点可用于访问列表索引,例如:
>>> from django.template import Template, Context
>>> t = Template('Item 2 is {{ items.2 }}.')
>>> c = Context({'items': ['apples', 'bananas', 'carrots']})
>>> t.render(c)
'Item 2 is carrots.'
#假设你要向模板传递一个 Python 字典。 要通过字典键访问该字典的值,可使用一个句点:
>>> from django.template import Template, Context
>>> person = {'name': 'Sally', 'age': '43'}
>>> t = Template('{{ person.name }} is {{ person.age }} years old.')
>>> c = Context({'person': person})
>>> t.render(c)
'Sally is 43 years old.'
#同样,也可以通过句点来访问对象的属性。 比方说, Python 的 datetime.date 对象有
#year 、 month 和 day 几个属性,你同样可以在模板中使用句点来访问这些属性:
>>> from django.template import Template, Context
>>> import datetime
>>> d = datetime.date(1993, 5, 2)
>>> d.year
1993
>>> d.month
5
>>> d.day
2
>>> t = Template('The month is {{ date.month }} and the year is {{ date.year }}.')
>>> c = Context({'date': d})
>>> t.render(c)
'The month is 5 and the year is 1993.'
# 这个例子使用了一个自定义的类,演示了通过实例变量加一点(dots)来访问它的属性,这个方法适
# 用于任意的对象。
>>> from django.template import Template, Context
>>> class Person(object):
... def __init__(self, first_name, last_name):
... self.first_name, self.last_name = first_name, last_name
>>> t = Template('Hello, {{ person.first_name }} {{ person.last_name }}.')
>>> c = Context({'person': Person('John', 'Smith')})
>>> t.render(c)
'Hello, John Smith.'
# 点语法也可以用来引用对象的方法。 例如,每个 Python 字符串都有 upper() 和 isdigit()
# 方法,你在模板中可以使用同样的句点语法来调用它们:
>>> from django.template import Template, Context
>>> t = Template('{{ var }} -- {{ var.upper }} -- {{ var.isdigit }}')
>>> t.render(Context({'var': 'hello'}))
'hello -- HELLO -- False'
>>> t.render(Context({'var': '123'}))
'123 -- 123 -- True'
# 注意这里调用方法时并* 没有* 使用圆括号 而且也无法给该方法传递参数;你只能调用不需参数的
# 方法。
if
if只能判断true 或 false 的值 不能进行复杂判断
{% if 1 %}
{% elif False %}
{% endif %}
for
{% for i in obj%}
#这里拿到的是值不是索引
{% endfor %}
li=[1,2,3]
{% for foo in li %}
{{ forloop.counter }}
{% endfor %}
<hr>
{% for foo in li %}
{{ forloop.counter0 }}
{% endfor %}
<hr>
{% for foo in li %}
{{ forloop.revcounter }}
{% endfor %}
-----------------------------------------------
1 2 3
0 1 2
3 2 1
filter & simple_tag
filter 过滤器
str='helloWord'
{{ str | upper }} 大写
<hr>
{{ str | lower }} 小写
<hr>
{{ str | first | upper }} 第一个字符大写
<hr>
{{ str | capfirst }} 首字母大写
-----------------------------------------
HELLOWORD
helloword
H
HelloWord
add:给变量加上相应的值
addslashes:给变量中的引号前加上斜线
copfirst:首字母大写
cut:从字符串中移除指定的字符
date:格式化日期字符串
defoult:如果值是False就替换成设置的默认值,否则用本来的值
add=5
{{obj|add:5}}
value2='hel l o wor ld'
{{value2|cut:' '}}
value3=datetime.datetime.now()
{{value3|date:'y-m-d'}}
value=[]
{{ value|default:'空的' }}
-----------------------------------
11
hellowrod
2017-10-18
空的
s1 = "<a href='#'>OK</a>"
{% autoescape off %}
{{ s1 }}
{% endautoescape %}
直接将标签进行渲染
{{s1|safe}}
作用同上
自定义filter
- 在app下创建一个目录叫(templatetags)
在文件夹下创建任意名称py文件
aaa.pyfrom django import template
from django.utils.safestring import mark_saferegister = template.Library()
@register.filter
def add_nub(a1, a2):
return a1 + a2在settings文件中注册app
- 在引用html顶部添加{% load py文件名%}
使用{{参数1|函数名:参数2}}
demo.html{% load aaa %}
Title
{{ ‘asd’|add_str:’zxc’ }}
自定义simple_tag
- 在app下创建一个目录叫(templatetags)
在文件夹下创建任意名称py文件
aaa.pyfrom django import template
from django.utils.safestring import mark_saferegister = template.Library()
@register.simple_tag
def add_nub(a1, a2):
return a1 + a2在settings文件中注册app
- 在引用html顶部添加{% load py文件名%}
使用{% 函数名 参数1 参数2 ……%}
demo.html{% load aaa %}
Title
{% add_nub 1 2 %}
filter 与 simple_tag 的比较:
- filter参数最多只能有2个,并且参数传递有明确要求 {{参数一|add_str:参数二 }} 不可以加空格
(filter如果想加入多个参数,可以传递一个列表然后再内部进行处理) - simple_tag参数可以有无数个
- filter 可以直接作为if 判断的条件
- simple_tag不可以嵌套在if中
filter 和 if 语句在模板语言中的应用
filter_demo.html
{% load my_tag %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/bloge/filter_demo/" method="post">
{% csrf_token %}
<input type="text" name="n1">
<input type="text" name="n2">
<input type="submit" value="ok">
</form>
{% if n1 and n2 %}
{% if n1|add_num:n2 > 100 %}
<p>{{ n1 }}+{{ n2 }} = {{ n1|add_num:n2 }} 大于100</p>
{% elif n1|add_num:n2 == 100 %}
<p>{{ n1 }}+{{ n2 }} = {{ n1|add_num:n2 }}等于100</p>
{% else%}
<p>{{ n1 }}+{{ n2 }} = {{ n1|add_num:n2 }}小于100</p>
{% endif %}
{% endif %}
</body>
</html>
my_tag.py
from django import template
register = template.Library()
@register.filter
def add_num(nub1, nub2):
return int(nub1) + int(nub2)
view
def filter_demo(request):
if request.method == 'POST':
n1 = request.POST.get('n1',None)
n2 = request.POST.get('n2',None)
print(n1,n2)
return render(request, 'filter_demo.html', locals())
elif request.method == 'GET':
return render(request, 'filter_demo.html')
模板的继承
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
.page-header{
height:50px;
background-color: rebeccapurple;
}
.page-body .menu{
height:500px;
background-color: antiquewhite;
float: left;
width:20%;
}
.page-body .menu a{
display: inline-block;
width: 100%;
float: left;
}
.page-body .content{
height:500px;
background-color: #92d1f4;
float: left;
width: 80%;
}
.page-footer{
height:30px;
background-color: #666666;
clear: both;
}
</style>
</head>
<body>
<div>
<div class="page-header">
</div>
<div class="page-body">
<div class="menu">
<a href="/bloge/ordered/">订单</a>
<a href="/bloge/shopping_car/">购物车</a>
</div>
<div class="content">
{% block content %}
What Happtend
{% endblock %}
</div>
</div>
<div class="page-footer"></div>
</div>
</body>
</html>
ordered.html
{% extends 'base.html' %}
{% block content %}
{{ block.super }}
<div>
订单
</div>
{% endblock %}
shopping_car.html
{% extends 'base.html'%}
{% block content %}
购物车
{% endblock %}
敲黑板
- 如果在模板中使用{% extends %},必须保证其为模板中的第一个模板标记。否则,模板继承将不起作用。
- 一般来说,基础模板中的{% block %}标签越多越好。记住,字模板不必定衣父模板中所有的代码块,因此你可以用合理的缺省对一些代码块进行填充,然后只对子模板所需的代码块进行(重)定义。俗话说,钩子越多越好
- 如果发觉自己在多个模板之间拷贝代码,你应该考虑将该代码段放置到父模板的某个{% block %}中。
- 如果你需要访问父模板中的块的内容,使用{{ block.super}}这个标签,这一个模板变量将会表现出父模板中的内容。如果只想在上级代码块基础上添加内容,而不是全部重载,该变量就显得非常有用了。
- 不允许在同一个模板中定义多个同名的{% block %},存在这样的限制是因为block标签的工作方式是双向的。也就是说,block标签不仅挖了一个要填的坑,也定义了在父模板中这个坑所填充的内容。如果模板中出现了两个相同名称的{% block %}标签,父模板将无从得知要使用哪个块的内容