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

时间:2021-09-26 09:43:40

1.创建一个模板库

使用模板过滤器的时候,直接把过滤器写在app里,
例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py 、 views.py 等处于同一层次。例如: 
books/ 
    __init__.py 
    models.py 
    templatetags/ 
    views.py 
在 templatetags 中创建两个空文件:一个 __init__.py (告诉Python这是一个包含了Python代码的包)和一个用来存放你自定义的标签/过滤器定义的文件。第二个文件的名字稍后将用来加载标签。例如,如果你的自定义标签/过滤器在一个叫作 poll_extras.py 的文件中,你需要在模板中写入如下内容: {% load poll_extras %}
{% load %} 标签检查 INSTALLED_APPS 中的设置,仅允许加载已安装的Django应用程序中的模板库。 
要成为有效的标签库,模块必须包含一个模块级的变量: register ,这是一个 template.Library 的实例。这个 template.Library 实例是包含所有已注册的标签及过滤器的数据结构。因此,在模块的顶部位置插入下述代码:
from django import template 
register = template.Library()

2. 自定义模板过滤器 
自定义过滤器就是有一个或两个参数的Python函数::
例如,在过滤器 {{ var|foo:”bar” }} 中 ,过滤器 foo 会被传入变量 var 和参数 bar 的内容。 
过滤器函数应该总有返回值,而且不能触发异常,它们都应该静静的失败。如果有一个错误发生,它们要么返回原始的输入字符串,要么返回空的字符串,无论哪个都可以。 
1)这里是一些定义过滤器的例子: 
def cut(value, arg): 
    "Removes all values of arg from the given string" 
return value.replace(arg, '') 
def lower(value): # Only one argument. 
    "Converts a string into all lowercase" 
    return value.lower() 
2)这里是一些如何使用过滤器的例子: 
    {{ somevariable|cut:”0″ }} 
3)下面是一个完整的模板库的例子,提供了一个 cut 过滤器: 
from django import template 
register = template.Library() 
@register.filter(name='cut') (装饰器)
def cut(value, arg): 
    return value.replace(arg, '')

@register.filter 
def lower(value): 
    return value.lower() 
   注意:1)在定义过滤器时,需要用 Library 实例来注册它,这样就能通过Django的模板语言来使用了: Python 2.4或更新,可以通过上面的装饰器   实现,如果不使用 name 参数,@register.filter那么Django将会使用函数名作为过滤器的名字
2)保证templatetags在已经INSTALLED_APPS里面,

3. 自定义模板标签 
(1)定义标签 
The time is {% current_time “%Y-%m-%d %I:%M %p” %}. 
(2)编写模板标签分析器mytag.py 
from django import template 
def do_current_time(parser, token): 
    try: 
        # split_contents() knows not to split quoted strings. 
        tag_name, format_string = token.split_contents() 
    except ValueError: 
        msg = '%r tag requires a single argument' % token.contents()[0] 
        raise template.TemplateSyntaxError(msg) 
    return CurrentTimeNode(format_string[1:-1]) 
(3) 编写模板节点 
import datetime 
class CurrentTimeNode(template.Node): 
    def __init__(self, format_string): 
        self.format_string = format_string 
    def render(self, context): 
        now = datetime.datetime.now() 
        return now.strftime(str(self.format_string)) 
(4) 注册标签 
register = template.Library() 
register.tag(’current_time’, do_current_time) 
或 
@register.tag(name=”current_time”) 
def do_current_time(parser, token): 
# …

(4) 简单标签的快捷方式 
Django 提供了一个帮助函数: simple_tag 。这个函数是 django.template.Library 的一个方法,它接受一个只有一个参数的函数作参数,把它包装在 render 函数和之前提及过的其他的必要单位中,然后通过模板系统注册标签。
我们之前的的 current_time 函数于是可以写成这样:

def current_time(format_string): 
    return datetime.datetime.now().strftime(format_string) 
register.simple_tag(current_time) 
在Python 2.4中,也可以使用修饰语法: 
@register.simple_tag 
def current_time(token): 
… 
有关 simple_tag 辅助函数,需要注意下面一些事情: 
传递给我们的函数的只有(单个)参数。 
在我们的函数被调用的时候,检查必需参数个数的工作已经完成了,所以我们不需要再做这个工作。 
参数两边的引号(如果有的话)已经被截掉了,所以我们会接收到一个普通字符串。

5. 包含标签 
(1)定义标签 
{% show_results poll %} 
(2)标签函数 
@register.inclusion_tag('books/books_for_author.html') 
def show_books_for_author(author): 
    books = author.book_set.all() 
    return {'books': books} 
(3)标签模板 
<ul> 
{% for book in books %} 
    <li> {{ book }} </li> 
{% endfor %} 
</ul>

随机推荐

  1. Kafka 消息存储及检索&lpar;作者:杜亦舒&rpar;

    Kafka 消息存储及检索 原创 2016-02-29 杜亦舒 性能与架构 Kafka是一个分布式的消息队列系统,消息存储在集群服务器的硬盘Kafka中可以创建多个消息队列,称为topic,消息的生产 ...

  2. R语言学习笔记:生成序列(Genenrating Sequences&rpar;

    R提供了多种生成不同类型序列的方法.如: > x<-1:20 > x [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 1 ...

  3. HDU 1695 GCD(欧拉函数&plus;容斥原理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695 题意:x位于区间[a, b],y位于区间[c, d],求满足GCD(x, y) = k的(x, ...

  4. 数据结构——AVL平衡树

    1.是二叉搜索树(Binary Search Tree) 2.树和所有左右子树高度之差为-1,0,1 平衡因子(balance factor) =右子树高度-左子树高度 平衡化旋转: 1.从插入位置向 ...

  5. 初识Python-web框架的这两天

    前段时间打算学习python,其实时间蛮紧张的,看看文字教程,累了就看视频教程.算是把基本的语法过了一遍,但是OOP就费了好大的气力 ,C里有的对象,继承,等等等,还算能理解.不过高级点的就理解起来吃 ...

  6. Spring&lowbar;构造注入

    依赖注入的第二种注入方式:构造器注入 创建带参数的构造方法,参数类型为注入类的类型 项目要先添加spring支持: package com; public class Computer { priva ...

  7. &lbrack;JSOI2008&rsqb;球形空间产生器sphere

    Sol 设一个dis,就有n+1个方程,消掉dis,就只有n个方程,组成一个方程组,高斯消元就好(建议建立方程时推一下,很简单) # include <bits/stdc++.h> # d ...

  8. 开始ITGEGE教育社区的视频录制----嵌入式基础知识讲解

    从8月份开始,陆陆续续要对我的第一份兼职工作ITGEGE讲师做教学视频录制了,本人水平有限,我只讲一些开发在工作中的应用,其它细节的东西不做深究,毕竟本人工作经验和精力也有限,白天要上班,特别是最近又 ...

  9. flume中HdfsSink参数说明

    flume到hdfsSink: type hdfs path 写入hdfs的路径,需要包含文件系统标识,比如:hdfs://namenode/flume/webdata/ 可以使用flume提供的日期 ...

  10. Zabbix二次开发&lowbar;02获取数据

    最近准备写一个zabbix二次页面的呈现.打算调用zabbix api接口来进行展示. 具体流程以及获取的数据. 1.  获得认证密钥    2.  获取zabbix所有的主机组    3.  获取单 ...