Django 自定义 过滤器和模板标签
代码布局(自定义的代码,放在哪里) 二种方式:
1. 某个app特有的
-app 目录下,templatetags 文件夹 ** 必需是这个名称的包(目录中有__init__.py文件)
-再到 templatetags 文件夹下创建python模块(py文件)
2. 定义复用
-创建一个新的app,将他们定义在新的app中,在INSTALL_APPS
注册,然后就可以应用
-在 templatetags 文件夹下新建 tags.py #文件名自己取
以下为文件内容:
# 自定义模板标签 和 过滤器 from django.template import Library def to_male(value, arg='zh'): dic = { 'zh': ('女', '男'), 'en': ('famle', 'male') } return dic[arg][value] register = Library() # 实例化 Library对象, *****变量名 必须为:register register.filter('to_male', to_male)
{% load static %} # 加载 静态文件路径设置 {% load tags %} # 加载 自定义<过滤器和 模板标签>库 <div> <table class="table"> <tr> <td>序号</td> <td>名字</td> <td>性别</td> <td>年龄</td> </tr> {#for 模板 endfor#} {% for stu in student %} {# if 模板 endif #} <tr {% if stu.sex == '0' %}style="color:red" {% endif %}> {# url模板 传url 和参数#} <td ><a href="{% url 'student:detail' stu.id %}">{{ stu.id }}</a></td> <td>{{ stu.name}}</td> <td>{{ stu.sex|to_male }}</td> <td>{{ stu.age }}</td> </tr> {% endfor %} </table> </div>
运行!
开门红 : 报错 自定义过滤器没有注册
解决方案:
settings.py templates:中增加:
定义一个包含标签inclusion_tag
# 定义一个包含标签inclusion_tag def show_list_as_ul(value): # value 接收来自 context的变量 ,前提:注册时 takes_context=True return {'ls': value} # 将 value 转换成一个ls, 变量传递给 html模板 register.inclusion_tag(name='show_list_as_ul', filename='../templates/show_list_as_ul.html', takes_context=True) # 接收来自 view 的context变量,用 show_list_as_ul.html模板样式去显示
<!--这 show_as_list 的 inclusion_tag 的模板--> <ul> {% for l in ls %} <li>{{ l }}</li> {% endfor %} #ls 变量 来自模板标签 </ul>
使用时在html模板文件上方 {% load filters %}
# 接收来自 views 的 定义方式
def show_list_as_ul(value): # value 接收来自 context的变量 return {'ls': value} # 将 value 转换成一个ls, 变量传递给 模板 register.inclusion_tag(name='show_list_as_ul', filename='show_list_as_ul.html') #我的 html模板放在 app/template下,一开始怎么试都失败...
# 接收来自 view 的context变量,用 show_list_as_ul.html模板样式去显示
后来修改为以下代码:
# 自定义模板标签 和 过滤器 from django.template import Library from datetime import datetime def to_male(value, arg='zh'): ''' :param value: 从上下文context中获取值 0为女,1为男 :param arg: 中英文 :return: 性别 ''' dic = { 'zh': ('女', '男'), 'en': ('famle', 'male') } return dic[arg][value] register = Library() register.filter('to_male', to_male) # 自定义简单模板标签 def c_time(format_str='%Y-%m-%d %H:%M:%S'): now = datetime.now() return now.strftime(format_str) register.simple_tag(func=c_time, name='c_time') # 自定 简单标签simple_tag 接收 views 中render的 上下文变量 context # - 把注册器的 takes_context=True, def c_time2(context): # 第一个参数 必须是 context,名字不能错. now = datetime.now() return now.strftime(context['format_str']) # 接收 context['format_str']的值 register.simple_tag(func=c_time2, takes_context=True, name='c_time2') # 自定义 包含标签 # 通过 render 另外一个模板 来展示数据 @register.inclusion_tag('show_list_as_ul.html') def show_list_as_ul(value): # 接收调用时传递的 模板变量 return {'li': value} #返回 字典 # register.inclusion_tag(filename='show_list_as_ul.html', func=show_list_as_ul, name='show_ul')
成功!
# 自定义 包含标签 # 通过 render 另外一个模板 来展示数据 @register.inclusion_tag('show_list_as_ul.html') def show_list_as_ul(value, style): # value 接收调用时传递的 模板变量, stlye 给li 的样式 return {'li': value, 'style': style} #返回 字典, 传递style 给 html模板.
#show_list_as_ul.html <ul class="list-group"> <!--li为自定义模板标签传递的 值--> {% if style == 1 %} {% for l in li %}<li class="list-group-item">{{ l }}</li>{% endfor %} {% elif style == 2 %} {% for l in li %}<li class="list-group-item"><span class="badge">{{ l }}</span> </li>{% endfor %} {% else %} {% for l in li %}<a href="#" class="list-group-item active">{{ l }}</a>{% endfor %} {% endif %} </ul>
# index.html <div> <table class="table"> <tr> <td>序号</td> <td>名字</td> <td>性别</td> <td>年龄</td> <td>course</td> </tr> {#for 模板 endfor#} {% for stu in student %} {# if 模板 endif #} <tr {% if stu.sex == 0 %}style="color:red" {% endif %}> {# url模板 传url 和参数#} <td ><a href="{% url 'student:detail' stu.id %}">{{ stu.id }}</a></td> <td>{{ stu.name}}</td> <td>{{ stu.sex|to_male }}</td> <td>{{ stu.age }}</td> <td>{% show_list_as_ul stu.course 1 %}</td> </tr> {% endfor %} </table> </div>