1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 0325 Django自定义过滤器和自定义模板标签

0325 Django自定义过滤器和自定义模板标签

时间:2022-02-13 15:11:43

相关推荐

0325 Django自定义过滤器和自定义模板标签

代码布局(死去活来)

自定义要先解决几个问题:

1). 在哪里定义,要将代码写在哪里?

app目录下的名为templatetags的文件夹,必须叫这个名字。这个文件夹必须是一个python的包(python package),这个文件夹下一定有一个__init__.py的文件自定义的模板标签,或模板过滤器就放在这个包下的python模块中(python脚本文件)app必须在settings中被注册

I.自定义模板过滤器

定义

自定义过滤器就是一个python函数,它有1个或2个参数。

第一个参数就是那个传进来的模板变量第二个参数是一个普通参数,可以是默认参数,也可以不要这个参数

依旧以teacher应用的案例为例子:如何将性别从男1女0的二进制显示变成我们看得懂的汉字或者英文字男male女female呢?简言之,就是接收0和1,返回女和男

注册并定义一个过滤器:

from django.template import Libraryregister = Library() # 必须用register这个变量名def my_male(value):'''转换性别的过滤器:param value::return:'''map = {0:'女',1:'男'}return map[value]register.filter(my_male) # 注册自定义过滤器

在模板中使用

Step1. load标签,引入自定义的过滤器模块,也就是templatetags包里的那个python文件teacher_tags.py

{% load teacher_filters %}

......

step2. 在表格tbody当中,写入在过滤器文件中定义好的过滤器名my_male,

<td>{{ student.sex|my_male }}</td>

注意:新建了templatetags的文件夹,要重启一下django服务。

2个参数:

需求:有中英文双语显示性别,则可以传入两个参数:

'''转换性别的过滤器:param value::return:'''map = {'zh': {0:'女', 1:'男'},'en': {0:'Female', 1:'Male'},}return map[value][lang]

给变量命名

过滤器变量的名字可以根据实际需要自己定义,避免名字重复或者名字太长的情况。

比如把def my_male(value, lang):改成def aaa(value, lang)

然后在模板html里面将原来的<td>{{ student.sex|my_male }}</td>改成<td>{{ student.sex|aaa }}</td>

II.自定义模板标签

干任何事情

标签类型

1. 简单标签

django.template.Library.simple_tag()

接受许多参数,并根据输入的参数和外部信息,进行处理后返回结果

创建、注册简单标签

代码布局在templatetags目录下,新建一个teacher_tags.py的文件

from django.template import Libraryfrom datetime import datetimeregister = Library() # 必须用register这个变量名,必须要写def current_time(format_str='%Y-%m-%d %H:%M:%S'):"""就输出当前时间"""return datetime.now().strftime(format_str)#注册register.simple_tag(current_time, name='current')

在模板中使用

{% load teacher_tags %}.....<h1>学生列表</h1><p>当前时间:{% current %}</p>

<插入定义好的过滤器加载到模板当中图片>

运行结果:

传值

{% current format_str= %}

运行结果:

另外,{% current '%Y-%m-%d' %}也一样能显示出年月日格式的当前时间

模板标签就是一个函数,跟普通函数的传参一样,可以传字符串、模板变量、关键字参数

再举个例子:

先在teacher应用目录下的views视图文件里,我们将上下文context函数中传入’format_str’:’%H:%M:%S’,

return render(request, 'teacher/student_list_page.html',context={'students':students,'format_str': '%H:%M:%S',})

再回到学生页面模板(也就是前端html页面)中,此时format_str则作为一个模板变量。

<p>当前时间:{% current format_str %}</p>

运行结果:

使用上下文变量

在自定义标签中,使用当前模板中的所有的上下文变量context

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)

语法格式:context``````take_context组成一对

class=‘new_year’

III. 包含标签(装饰器)

定义

通过渲染另外一个模板展示数据,以后django admin就会用到这个

@register.inclusion_tag('teacher/show_list.html')def show_list(list_data):# 一个嵌套标签,实现展示列表数据return {'ls': list_data}

继续以teacher应用中学生列表的例子为范例:

先在views里面的student_list_view和student_detail_view里面的学生列表中加入hobby变量,并传入参数列表

def student_list_view(request):students = [{'id': 1, 'name': 'Adam', 'age': 19, 'sex': 1, 'hobby': ['篮球', '足球', '排球']},{'id': 3, 'name': 'Betty', 'age': 19, 'sex': 0, 'hobby': ['羽毛球', '毽子', '乒乓球']},{'id': 11, 'name': 'Cathy', 'age': 18, 'sex': 0, 'hobby': ['羽毛球', '毽子', '乒乓球']},{'id': 12, 'name': 'Daisy', 'age': 20, 'sex': 0, 'hobby': ['羽毛球', '毽子', '乒乓球']},{'id': 15, 'name': 'Ethan', 'age': 19, 'sex': 1, 'hobby': ['篮球', '足球', '排球']},{'id': 26, 'name': 'Adda', 'age': 19, 'sex': 0, 'hobby': ['篮球', '网球', '排球']},{'id': 27, 'name': 'Bryan', 'age': 20, 'sex': 1, 'hobby': ['篮球', '足球', '排球']},{'id': 38, 'name': 'Carmen', 'age': 18, 'sex': 0, 'hobby': ['篮球', '网球', '排球']},{'id': 39, 'name': 'Dolphin', 'age': 20, 'sex': 0, 'hobby': ['篮球', '网球', '排球']},{'id': 40, 'name': 'Evan', 'age': 19, 'sex': 1, 'hobby': ['篮球', '网球', '排球']},]

def student_detail_view(request, pk):students = {1: {'id': 1, 'name': 'Adam', 'age': 19, 'sex': 1, 'hobby':['篮球','足球','排球']},3: {'id': 3, 'name': 'Betty', 'age': 19, 'sex': 0, 'hobby':['羽毛球','毽子','乒乓球']},11: {'id': 11, 'name': 'Cathy', 'age': 18, 'sex': 0, 'hobby':['羽毛球','毽子','乒乓球']},12: {'id': 12, 'name': 'Daisy', 'age': 20, 'sex': 0, 'hobby':['羽毛球','毽子','乒乓球']},15: {'id': 15, 'name': 'Ethan', 'age': 19, 'sex': 1, 'hobby':['篮球','足球','排球']},26: {'id': 26, 'name': 'Adda', 'age': 19, 'sex': 0, 'hobby':['篮球','网球','排球']},27: {'id': 27, 'name': 'Bryan', 'age': 20, 'sex': 1, 'hobby':['篮球','足球','排球']},38: {'id': 38, 'name': 'Carmen', 'age': 18, 'sex': 0, 'hobby':['篮球','网球','排球']},39: {'id': 39, 'name': 'Dolphin', 'age': 20, 'sex': 0, 'hobby':['篮球','网球','排球']},40: {'id': 40, 'name': 'Evan', 'age': 19, 'sex': 1, 'hobby':['篮球','网球','排球']},}

再回到学生列表模板前端html文件里添加一个表头"爱好",再在单元格td标签中添加ul标签,其中插入for标签,写入for item in student.hobby调用item,并加入带li标签的模板变量item

<table class="table"><thread><tr><th>学号</th><th>姓名</th><th>年龄</th><th>性别</th><th>爱好</th></tr></thread><tbody>{% for student in students %}<tr {% if student.sex == 0 %} style="background-color: lightpink"{% else %} style="background-color: aqua" {% endif %}>"<td><a href="{% url 'teacher:student_detail' student.id %}">{{ student.id }}</a></td><td>{{ student.name }}</td><td>{{ student.age }}</td><td>{{ student.sex|my_male:'en' }}</td><td><ul>{% for item in student.hobby %}<li>{{ item }}</li>{% endfor %}</ul></td></tr>{% endfor %}</tbody></table>

思考:当我们的模板里有很多数据需要填进去,并且还要设置不同的样式(CSS),有没有其他办法可以让这些数据填入在渲染的时候不用那么麻烦呢?那我们就可以用到包含标签(装饰器)的方法了。

在teacher_tags页面,新增定义

def show_list(list_data):'''这是一个嵌套标签,实现展示列表数据的功能:param list_data::return:'''return {'ls': list_data}

并在templates目录的teacher目录下新建一个show_list.html的模板前端页面。

在teacher_tags标签页顶部插入以下指令导入get_template模块

from django.template.loader import get_template

在return下方加入以下指令来导入该新建的模板:

t = get_template('teacher/show_list.html')register.inclusion_tag(show_list)

这里我们可以用一个装饰器来实现同样的功能:

@register.inclusion_tag('teacher/show_list.html')def show_list(list_data):'''这是一个嵌套标签,实现展示列表数据的功能:param list_data::return:'''return {'ls': list_data}

这样就可以把

t = get_template('teacher/show_list.html')

register.inclusion_tag(show_list)去掉了。

在新建的show_list.html里写入:

<ul>{% for l in ls %}<li>{{ l }}</li>{% endfor %}</ul>

那么学生列表页student_list_page前端里关于hobby的td标签就可以缩减为{% show_list student.hobby %}

<table class="table"><thread><tr><th>学号</th><th>姓名</th><th>年龄</th><th>性别</th><th>爱好</th></tr></thread><tbody>{% for student in students %}<tr {% if student.sex == 0 %} style="background-color: lightpink"{% else %} style="background-color: aqua" {% endif %}>"<td><a href="{% url 'teacher:student_detail' student.id %}">{{ student.id }}</a></td><td>{{ student.name }}</td><td>{{ student.age }}</td><td>{{ student.sex|my_male:'en' }}</td><td>{% show_list student.hobby %}</td></tr>{% endfor %}</tbody></table>

同样,在学生详情页的前端页面,也可以通过包含标签的方法,实现简洁的代码编写。

这个show_list.html等于单独拿出来做了一个格式模板,只负责显示格式的功能渲染,这样,当表格的数据项目有很多时,你就不需要去为每一个数据项目再去设置格式那么繁琐了。

引用上下文变量

@register.inclusion_tag('teacher/show_list.html', takes_context=True)def show_list(context, list_data):'''这是一个嵌套标签,实现展示列表数据的功能:param list_data::return:'''return {'ls': list_data, 'context': context}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。