本文在我的微信公众号的链接:https://mp.weixin.qq.com/s?__biz=MzU5NTU5MjcwNw==&mid=2247483674&idx=1&sn=173e575b357a85d880c4e0fac0d19884&chksm=fe6ed276c9195b60f32eb199dfdc73782280194363b32cfbc6ad74ed9cbdf0b0f4d7f88bab50&token=1798998824&lang=zh_CN#rd

扫码关注我的公众号                                                                            大佬打赏渠道

                            

1.自定义模板过滤器与标签的需求

Django框架模板的过滤器与标签就是在Django框架的模板文件中实现某种功能。Django框架自带有许多的模板过滤与标签,但有时候还需要自定义模板过滤器与标签。

以将数据库中存储的人员数据中性别这一项的数据传递显示到应用前端为例,在数据库中,为了节省存储空间,类似于只有 和 这种二值项数据,一般都用0和1存储。但这也为后端与前台的数据交互提出一个问题:前端向后端提出查看性别数据的请求,后端直接返回的是0和1的数据,并不符合人们的直接阅读习惯。而自定义模板过滤器就可以解决这个问题,它可以将传递过来的0和1对应的转化为人们更乐于接受的 和 这种显示的表示。当然,你也可以在后端将从数据库中读取出来的数据全部转化为对应的显示表示后再传递给模板文件,但是这样你的代码往往不够简练、清晰。

至于自定义标签,也可以解决类似上面的问题。但自定义模板标签更加强大,它可以干任何事情。

2.自定义模板过滤器与标签的代码布局

首要的问题是,自定义模板过滤器与标签在哪里定义?要将代码写在什么地方?

代码布局的要点

  • 代码写在app目录下的名为 tempaltetags的文件夹【必须叫这个名字】。这个文件夹必须是一个python的包,这个文件夹下一定要有 __init__.py的文件,最好直接创建 pythonpackage,将其命名为 tempaltetags,这样会自动包含 __init__.py文件。

  • 自定义的模板标签或模板过滤器就放在这个包下的python模块中(python脚本文件)

  • app必须在 settings.py中被注册

settings.py文件中在【 INSTALLED_APPS】配置中加上app应用名 teacher

  1. INSTALLED_APPS =[

  2. 'django.contrib.admin',

  3. 'django.contrib.auth',

  4. 'django.contrib.contenttypes',

  5. 'django.contrib.sessions',

  6. 'django.contrib.messages',

  7. 'django.contrib.staticfiles',

  8. # 实际中只在调试的时候用到staticfiles,实际布署的时候用的ngix

  9. 'teacher'

  10. ]

2.自定义模板过滤器

定义

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

  • 第一参数就是那个传进来的模板变量【任意数据类型】

  • 第二个参数是一个普通参数,可以是默认参数,也可以不要这个参数

例子:这里的自定义过滤器是将数据库中的性别 sex项中存储的值0和1转换为对应的女和男。

自定义过滤器的功能是: 接受0和1,分别转换成女和男

视图函数中数据库的模拟

sex为1代表男性,sex为0代表女性

  1. def student_list_view(request):

  2. students =[

  3. {'id':1,'name':'小明','age':18,'sex':1},

  4. {'id':3,'name':'小花','age':17,'sex':0},

  5. {'id':19,'name':'小李','age':18,'sex':1},

  6. {'id':100,'name':'小红','age':18,'sex':0},

  7. ]

  8. return render(request,'teacher/students_list.html',context={'students':students})

这里一共提供三种转换方法:if条件选择写法三目运算符写法字典键值对转换

其实,if条件选择写法三目运算符写法并没有本质区别,python中也没用像java或其他编程语言中有三目运算的专门写法,只不过将多行代码写到了一行中,使得你的程序更加 pythonic

以下便是三种方法的具体代码与注释:

  1. # 转换性别的过滤器

  2. # 接受0和1,分别转换成女和男

  3. def my_sex(value):

  4. """

  5. 转换性别的过滤器

  6. :param value:

  7. :return :

  8. """

  9. # if条件选择写法

  10. if value =='1':

  11. return'男'

  12. else:

  13. return'女'

  14. # 三目运算符写法

  15. return'男'if value else'女'

  16. # 字典键值对转换

  17. map ={

  18. 0:'女',

  19. 1:'男'

  20. }

  21. return map[value]

注册

自定义模板过滤器的注册有两种方法,一般用装饰器注册。

但是无论哪种方法,首先都要实例化一个 Library()对象。值得注意的是,接受实例化对象的变量名必须为register,不能有任何改变。

  1. from django.template importLibrary

  2. # 实例化

  3. register =Library()# 必须用register这个变量名

普通的注册方法

  1. '''

  2. 注册方法一:普通注册方法

  3. '''

  4. # 自定义filter

  5. def my_sex(value):

  6. """

  7. 转换性别的过滤器

  8. :param value:

  9. :return :

  10. """

  11. # if条件选择写法

  12. map ={

  13. 0:'女',

  14. 1:'男'

  15. }

  16. return map[value]

  17. # 注册,并命名为xxx,

  18. # 注意:命名后,自定义filter应用的时候用xxx

  19. register.filter('xxx',my_sex)

利用装饰器注册的方法

  1. '''

  2. 注册方法二:装饰器注册方法

  3. '''

  4. # 注册,并命名为xxx

  5. # 注意:命名后,自定义filter应用的时候用xxx

  6. @register.filter(name='xxx')

  7. def my_sex(value):

  8. """

  9. 转换性别的过滤器

  10. :param value:

  11. :return :

  12. """

  13. # if条件选择写法

  14. map ={

  15. 0:'女',

  16. 1:'男'

  17. }

  18. return map[value]

在模板中使用自定义过滤器

首先,load过滤器所在的py文件名,引入自定义的过滤器模块,也就是 templatetags包里的那个python文件。【注意:新建了 templatetags包,要重启一下Django服务】接下来,你就可以在模板文件中使用你的自定义过滤器了,自定义过滤器的用法与内置的过滤器用法完全一样,这里就不再赘述了。

在模板文件中加载自定义过滤器

  1. {% extends 'teacher/base.html'%}

  2. # 在模板文件中加载自定义过滤器

  3. {% load teacher_filter %}

  4. {% block title %}学生列表{% endblock %}

向自定义过滤器传递2个参数

这里有一个新的需求,如果我们的网页是面向世界的,需要支持多种语言,简单起见,譬如说就支持中文和英文。这时候如何实现语言的切换。具体应用场景还是以上面的例子来说。

首先,定义好一个能接受两个参数的自定义过滤器。

默认语言参数language为中文 'ch'

  1. def my_sex(value,laguage='ch'):

  2. """

  3. 转换性别的过滤器

  4. :param value:

  5. :return :

  6. """

  7. # if条件选择写法

  8. map ={

  9. 'zh':{0:'女',1:'男'},

  10. 'en':{0:'female',1:'male'}

  11. }

  12. return map[laguage][value]

其次,在自定义过滤器应用文件中加载自定义过滤器并应用。

  1. {% extends 'teacher/base.html'%}

  2. {% load teacher_filter %}

  3. {% block title %}学生列表{% endblock %}

  4. ...

  5. <td>{{ student.sex|my_sex:'en'}}</td>

  6. ...

最终效果

3.自定义模板标签

模板标签可以干任何事情

标签类型

(1).简单标签

简单标签与过滤器没有太大的区别

简单标签的注册: django.template.Library.simple_tag()

注册方法与自定义过滤器一样。

简单标签可以接受许多参数,处理后返回信息。

创建、注册一个简单标签的实例代码

  1. from django.template importLibrary

  2. from datetime import datetime

  3. register =Library()

  4. def current_time(format_str='%Y-%m-%d %H:%M:%S'):

  5. """

  6. 就输出当前时间

  7. :param format_str:

  8. :return:

  9. """

  10. return datetime.now().strftime(format_str)

  11. # 注册,并命名为current

  12. register.simple_tag(current_time,name='current')

模板中的使用

  1. {%extends'teacher/base.html'%}

  2. {% load teacher_tags %}

  3. ....

  4. <p>

  5. 当前时间:{% current format_str='%Y-%m-%d'}

  6. </p>

  7. # 跟普通函数的传参一样,字符串、模板变量、关键字参数都可以传递

  8. # 也可以直接写{% current '%Y-%m-%d' %}

  9. {% current format_str='%Y-%m-%d'%}

使用上下文变量

在自定义标签中,使用当前调用标签的视图函数中的上下文变量

使用当前模板中的上下文变量context

创建、注册

  1. from django.template importLibrary

  2. from datetime import datetime

  3. register =Library()

  4. # 自定义简单标签的函数中也要传递context

  5. def current_time(context,format_str='%Y-%m-%d %H:%M:%S'):

  6. """

  7. 就输出当前时间

  8. :param format_str:

  9. :return:

  10. """

  11. return datetime.now().strftime(format_str),[x for x in context['students']if x['sex']==1]

  12. # 注意,在注册的时候要加上 takes_context=True

  13. register.simple_tag(current_time,name='current',takes_context=True)

应用

  1. {% extends 'teacher/base.html'%}

  2. {% load teacher_filter %}

  3. {% load teacher_tags %}

  4. {% block title %}学生列表{% endblock %}

  5. {% block content %}

  6. <h1>学生列表</h1>

  7. <p>当前时间和男性学生分别为:{% current format_str='%Y-%m-%d'%}</p>

  8. <table class="table">

效果

(2).包含标签(嵌套标签)

通过渲染另外一个模板展示数据

创建、注册一个包含标签

  1. from django.template importLibrary

  2. from datetime import datetime

  3. from django.template.loader import get_template

  4. register =Library()

  5. # 利用装饰器注册自定义包含标签,等同于下面的那种注册方式

  6. @register.inclusion_tag('teacher/show_list.html')

  7. def show_list(list_data):

  8. # 一个嵌套标签,实现展示列表数据

  9. return{'ls':list_data}

  10. # 普通方式注册自定义包含标签,等同于上面的装饰器注册方法

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

  12. # register.inclusion_tag(t)(show_list)

包含标签包含的模板文件

这个模板文件存放路径【 templates/teacher/show_list.html

  1. <ul>

  2. {%for l in ls %}

  3. <li>{{ l }}</li>

  4. {% endfor %}

  5. </ul>

显示模板中的应用

  1. {%extends'teacher/base.html'%}

  2. {% load teacher_filter %}

  3. {% load teacher_tags %}

  4. ...

  5. <td>

  6. <!-自定义包含标签的应用->

  7. {% show_list student.hobby %}

  8. </td>

  9. ...

包含标签的数据流传递路径:

包含标签的作用:

包含标签通过渲染另外一个模板来展示数据,其主要作用便是为了省工省力,有时候一个页面中,我们需要在多处使用类似的复杂操作,这个时候可以通过包含标签来定义其行为,在原来的位置使用包含标签即可,同样的操作使用包含标签只需要写一次代码便可实现多次功能。

Django框架之【自定义模板过滤器与标签】的更多相关文章

  1. Django——模板层(template)(模板语法、自定义模板过滤器及标签、模板继承)

    前言:当我们想在页面上给客户端返回一个当前时间,一些初学者可能会很自然的想到用占位符,字符串拼接来达到我们想要的效果,但是这样做会有一个问题,HTML被直接硬编码在 Python代码之中. 1 2 3 ...

  2. $Django 模板层(变量、过滤器 、标签)、自定义(模板过滤器,标签)

    1 模版语法之变量:详见源码  -{{ 变量 }}:******重要******{#相当于print了该变量#} {#只写函数名 相当于()执行了#}<p>函数:{{ test }}< ...

  3. django-5-自定义模板过滤器及标签

    <<<代码布局(自定义的代码放哪里)>>> (1)某个app特有的  1.一般放app目录下 固定名为templatetags 的python文件夹里鸭,如果是别的 ...

  4. 第三百一十四节,Django框架,自定义分页

    第三百一十四节,Django框架,自定义分页 自定义分页模块 #!/usr/bin/env python #coding:utf-8 from django.utils.safestring impo ...

  5. Django框架简介及模板Template,filter

    Django框架简介 MVC框架和MTV框架 MVC,全名是Model View Controller,是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model).视图(View) ...

  6. Django框架——基础之模板系统(template文件夹)

    ---恢复内容开始--- 1. 常用语法 需要记住两组特殊符号:{{  }}  和 {%  %}. 在运用到变量的时候使用{{  }},如果是跟逻辑相关的话就使用{%  %}. 在Django模板(t ...

  7. Django框架(十一):模板介绍、模板语言、模板继承、HTML转义

    1. 模板介绍 1.1 模板的功能 产生html,控制页面上展示的内容.模板文件不仅仅是一个html文件. 模板文件包含两部分内容: 静态内容:css.js.html. 动态内容:用于动态去产生一些页 ...

  8. DJANGO之自定义模板过滤器

    我查找了DJANGO模板的过滤器,好像指定字符串包含指定关-键字符的过滤器没有呢, 没有硬着头-皮,按网上其它人的作法,写了一个,成功了...:) 参考URL: http://liuzhijun.it ...

  9. Django框架详细介绍---模板系统

    Django模板系统 官方文档: https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#std:templatetag-for 1 ...

随机推荐

  1. swift开发常用代码片段

    // 绑定事件 cell.privacySwitch.addTarget(self, action: #selector(RSMeSettingPrivacyViewController.switch ...

  2. LeetCode-Insertion Sort List[AC源码]

    package com.lw.leet5; /** * @ClassName:Solution * @Description: * Insertion Sort List * Sort a linke ...

  3. 教你破解MyEclipse到2016年【图文详解】

    1.首先确定JDK以及环境变量没有问题.因为破解工具包里的run.bat是调用java命令执行jar包,如果环境变量没有配置好,那就运行不了了.2.解压破解包,双击[run.bat]打开破解界面: 3 ...

  4. 学习 C++的用途,(前辈总结)

    C++准确说是一门中级语言,介于汇编和高级语言之间吧,要求程序员了解计算机的内部数据存储.个人认为,作为学生还是花功夫学C++,因为<设计模式><数据结构>这些课程基本上还是C ...

  5. bzoj 1455: 罗马游戏

    1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MB Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最 ...

  6. HDU 1452 欧拉定理

    让你求$2004^x$所有因子之和,因子之和函数是积性函数$\sigma(n)=\sum_{d|n}d=\prod_{i=0}^{m}(\sum_{j=0}^{k_i}{P_i^{j}})$可用二项式 ...

  7. JVM调优总结(6):新一代的垃圾回收算法

    垃圾回收的瓶颈 传统分代垃圾回收方式,已经在一定程度上把垃圾回收给应用带来的负担降到了最小,把应用的吞吐量推到了一个极限.但是他无法解决的一个问题,就是Full GC所带来的应用暂停.在一些对实时性要 ...

  8. IIC总线学习

    IIC总线 IIC协议简要说明: 1.2条双向串行线,一条数据线称为SDA,一条时钟线SCL,双向半双工 2.传输的设备之间只是简单的主从关系,主机可以作为主机发送也可以作为主机接收,任何时候只能由一 ...

  9. MySQL性能优化之道

    1.in和not in子查询优化 not in 是不能命中索引的,所以以下子查询性能很低. 如果是确定且有限的集合时,可以使用.如 IN (0,1,2). 用 exists或 notexists代替 ...

  10. 【BZOJ】4872: [Shoi2017]分手是祝愿 期望DP

    [题意]给定n盏灯的01状态,操作第 i 盏灯会将所有编号为 i 的约数的灯取反.每次随机操作一盏灯直至当前状态能够在k步内全灭为止(然后直接灭),求期望步数.n,k<=10^5. [算法]期望 ...