前言
为什么要自定义过滤器和标签:当Django自带的过滤器及标签不能满足我们需求的时候,我们就需要自定义过滤器和标签
代码布局
- 自定义过滤器及标签必须放在APP目录下名为
templatetags
的文件夹下,必须叫这个名字,这个文件夹必须是个Python的包,所以必须有一个__init__.py
文件。 - 自定义的模板标签或模板过滤器就放在这个包下的Python模块中。
- APP必须在
settings.py
文件中被注册
1. 自定义模板过滤器
1.1 定义
- 自定义过滤器就是一个Python函数,他只能有个1个或2个参数
- 第一个参数就是那个传进来的模板变量
- 第二个参数是一个普通参数,可以是默认参数,也可以不要这个参数
1.2 注册
在templatetags
文件夹下我们创建一个teacher_filters.py
文件,定义和注册过滤器的代码如下
#这是一个自定义过滤器
from django.template import Library
register = Library() #必须用register这个变量名
def convert_male (value):
# 转换性别过滤器
map = {
'301':'男',
'302':'女'
}
return map[value]
register.filter(convert_male) #注册convert_male这个过滤器
1.3 在模板中使用
- 用
load
标签,引入刚才创建的teacher_filters.py
模块文件
{% load teacher_filters %} #引入自定义过滤器
...
<td>{{student.sex|convert_male}}</td> #使用自定义过滤器
...
补充
- 过滤器命名:我们还可以给过滤器起一个名字,在模板中使用这个名字
#这是一个自定义过滤器
from django.template import Library
register = Library() #必须用register这个变量名
def convert_male (value,lang='zh'):
# 转换性别过滤器
map = {
'zh':{'301':'男', '302':'女'}
'en':{'301':'male','302':'female'}
}
return map[lang][value]
register.filter('name',convert_male)
{% load teacher_filters %} #引入自定义过滤器
...
<td>{{student.sex|name:'en'}}</td> #使用自定义过滤器的名字
...
2.自定义模板标签
标签类型
-
简单模板标签
简单标签和自定义过滤器非常类似,不同的是他可以定义许多参数
## 定义一个自定义简单模板标签
from django.template import Library
from datetime import datetime
register = Library()
#第一种注册
@register.simple_tag(name='current')
def current_time (format_str='%Y-%m-%d %H:%M:%S'):
#输出当前时间
return datetime.now().strftime(format_str)
#第二种注册
#register.simple_tag(current_time,name='current')
使用上下文变量:我们还可以将视图中所有的模板变量context
传递给自定义标签
## 定义一个自定义简单模板标签
from django.template import Library
from datetime import datetime
register = Library()
def current_time (context,format_str='%Y-%m-%d %H:%M:%S'):
#输出当前时间
return datetime.now().strftime(format_str)
#注册自定义标签
register.simple_tag(current_time,name='current',takes_context=True) #必须将takes_context参数为True
-
包含标签|嵌套标签
通过渲染另外一个模板来展示数据,具体方法如下
1.首先在视图文件中定义一个列表数据
def students_view(request):
students = [
{'name':'李萌','sex':'302','age':'16','hobby':['看书','看电影','骑车']},
{'name':'张杨','sex':'301','age':'80','hobby':['看书','看电影','骑车']},
{'name':'刘猛','sex':'301','age':'22','hobby':['看书','看电影','骑车']},
{'name':'鸣人','sex':'301','age':'18','hobby':['看书','看电影','骑车']},
{'name':'小李','sex':'301','age':'24','hobby':['看书','看电影','骑车']},
{'name':'何炅','sex':'301','age':'66','hobby':['看书','看电影','骑车']},
{'name':'饭岛爱','sex':'302','age':'16','hobby':['看书','看电影','骑车']},
]
2.再创建一个模板文件show_list.html
<ul>
{% for i in lt %}
<li>{{i}}</li>
{% endfor %}
</ul>
3.再定义和注册我们的包含标签
from django.template import Library
from datetime import datetime
from django.template.loader import get_template
#注册+定义包含标签
@register.inclusion_tag('teacher/show_list.html')
def show_list(list_data):
return {'lt':list_data}
#或者这样注册,但是这种方法太麻烦,一般很少使用
# t = get_template('teacher/show_list.html')
# register.inclusion_tag(t)(show_list)
4.在模板文件中使用
{% extends 'teacher/base.html' %}
{% load teacher_filters %}
{% load teacher_tags %} #导入自定义标签
<table class="table">
<thead>
<tr>
<th>序号</th>
<th>名字</th>
<th>性别</th>
<th>年龄</th>
<th>爱好</th>
</tr>
</thead>
<tbody>
{% for student in students %}
<tr {% if student.sex == '女' %} style="background-color: darksalmon"
{% else %} style="background-color:aquamarine"
{% endif %}>
<td>{{forloop.counter}}</td>
<td>{{student.name}}</td>
<td>{{student.sex|convert_male}}</td>
<td>{{student.age}}</td>
<td>
{% show_list student.hobby %} #使用自定义包含标签
</td>
</tr>
{% endfor %}