Django 自定义模版标签和过滤器
实现自定义过滤器
1. 创建register变量
register = template.Library()
2. 定义过滤器函数
#移除字符串中var的arg字串
return var.replace(arg, '')
"Converts a string into all lowercase"
return value.lower()
3. 注册过滤器函数
#第二个就是你的过滤器函数引用名
register.filter('remove', remove)
register.filter('lower', lower)
def remove(value, arg):
return value.replace(arg, '')
@register.filter
def lower(value):
return value.lower()
register = template.Library()
@register.filter(name='remove')
def remove(value, arg):
return value.replace(arg, '')
@register.filter
def lower(value):
return value.lower()
实现自定义tag
了解模板编译过程
{% ifequal name.birthday today %}
Happy birthday!
{% else %}
Be sure to come back on your birthday
for a splendid surprise message.
{% endifequal %}
- Text node: "Hello, "
- Variable node: person.name
- Text node: ".\n\n"
- IfEqual node: name.birthday and today
创建tag实战
1. 定义Node节点类,实现render方法
from django import template
#这一句还是要的
register = template.Library()
class CurrentTimeNode(template.Node):
def __init__(self, format_string):
self.format_string = str(format_string)
def render(self, context):
now = datetime.datetime.now()
#返回的是格式化后的时间表示字符串
return now.strftime(self.format_string)
2. 创建Compilation函数
try:
tag_name, format_string = token.split_contents()
except ValueError:
msg = '%r tag requires a single argument' % token.split_contents()[0]
raise template.TemplateSyntaxError(msg)
return CurrentTimeNode(format_string[1:-1])
每一个tag的编译函数都需要两个参数parser和token:
3. 注册tag
def do_current_time(parser, token):
# ...
@register.tag
def shout(parser, token):
# ...
不用名字,表示默认使用函数名
import datetime
register = template.Library()
@register.filter(name='remove')
def remove(value, arg):
return value.replace(arg, '')
@register.filter
def lower(value):
    return value.lower()
class CurrentTimeNode(template.Node):
    def __init__(self, format_string):
        self.format_string = str(format_string)
    def render(self, context):
        now = datetime.datetime.now()
        return now.strftime(self.format_string)
    def do_current_time(parser, token):
        try:
            tag_name, format_string = token.split_contents()
        except ValueError:
            msg = '%r tag requires a single argument' % token.split_contents()[0]
            raise template.TemplateSyntaxError(msg)
     return CurrentTimeNode(format_string[1:-1])
register.tag('current_time', do_current_time)
4. 运行


复杂的实现自定义tag的其他几种方法
1. 在Node类的render函数中设置context
now = datetime.datetime.now()
#设置context对象的值
context['current_time'] = now.strftime(self.format_string)
# render函数一定要返回字符串,即使是空串
return ''
<<SPAN style="COLOR: #0000ff">p>The time is {{ current_time }}.</<SPAN style="COLOR: #0000ff">p>
<<SPAN style="COLOR: #0000ff">p>The current time is {{ my_current_time }}.</<SPAN style="COLOR: #0000ff">p>
class CurrentTimeNode3(template.Node):
def __init__(self, format_string, var_name):
#增加自定义变量名的参数
self.format_string = str(format_string)
self.var_name = var_name
def render(self, context):
now = datetime.datetime.now()
context[self.var_name] = now.strftime(self.format_string)
return ''
def do_current_time(parser, token):
    #使用正规表达式来处理token
    try:
    # 使用string.split(sep[, maxsplit]),1代表最大分割数,也就是
    # 分割后会产生maxsplit+1个元素
    # 这里分割后的结果为(get_current_time, '"%Y-%M-%d %I:%M %p" as my_current_time')
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        msg = '%r tag requires arguments' % token.contents.split_contents()[0]
        raise template.TemplateSyntaxError(msg)
    #使用()代表正则组,匹配as两边的字符串
    m = re.search(r'(.*?) as (\w+)', arg)
    if m:
        fmt, var_name = m.groups()
    else:
        msg = '%r tag had invalid arguments' % tag_name
        raise template.TemplateSyntaxError(msg)
    #如果格式没被引号引用,报错
    if not (fmt[0] == fmt[-1] and fmt[0] in ('"', "'")):
        msg = "%r tag's argument should be in quotes" % tag_name
        raise template.TemplateSyntaxError(msg)
    # [1:-1]去除格式两边的引号
    return CurrentTimeNode3(fmt[1:-1], var_name)
register.tag('get_current_time', do_current_time)

2. 实现块作用区域的tag
nodelist = parser.parse(('endcomment',))
parser.delete_first_token()
return CommentNode()
class CommentNode(template.Node):
    def render(self, context):
    return ''
3. 在块作用tag中保留context内容
This will appear in uppercase, {{ user_name }}.
{% endupper %}
nodelist = parser.parse(('endupper',))
parser.delete_first_token()
return UpperNode(nodelist)
class UpperNode(template.Node):
    def __init__(self, nodelist):
        self.nodelist = nodelist
def render(self, context):
        output = self.nodelist.render(context)
        return output.upper()
4. 快速创建简单tag的方法
try:
return datetime.datetime.now().strftime(str(format_string))
except UnicodeEncodeError:
return ''
register.simple_tag(current_time)
def current_time(token):
# ...
5. 创建Inclusion Tag
<<SPAN style="COLOR: #0000ff">li>The Cat In The Hat</<SPAN style="COLOR: #0000ff">li>
<<SPAN style="COLOR: #0000ff">li>Hop On Pop</<SPAN style="COLOR: #0000ff">li>
<<SPAN style="COLOR: #0000ff">li>Green Eggs And Ham</<SPAN style="COLOR: #0000ff">li>
</<SPAN style="COLOR: #0000ff">ul>
- 定义函数
books = Book.objects.filter(authors__id=author.id)
return {'books': books}
- 创建另一个模板文件book_snippet.html
{% for book in books %}
<<SPAN style="COLOR: #0000ff">li>{{ book.title }}</<SPAN style="COLOR: #0000ff">li>
{% endfor %}
</<SPAN style="COLOR: #0000ff">ul>
- 注册tag
def jump_link(context):
return {
'link': context['home_link'],
'title': context['home_title'],
}
模板文件link.html为
创建自定义模板加载类
from django.template import TemplateDoesNotExist
import zipfile
def load_template_source(template_name, template_dirs=None):
"Template loader that loads templates from a ZIP file."
#从settings.py配置文件中读取属性TEMPLATE_ZIP_FILES的值,默认返回空列表
template_zipfiles = getattr(settings, "TEMPLATE_ZIP_FILES", [])
# Try each ZIP file in TEMPLATE_ZIP_FILES.
for fname in template_zipfiles:
try:
z = zipfile.ZipFile(fname)
source = z.read(template_name)
except (IOError, KeyError):
continue
z.close()
# 找到一个可用的文件就返回
template_path = "%s:%s" % (fname, template_name)
return (source, template_path)
# 如果一个zip文件没找到,报错
raise TemplateDoesNotExist(template_name)
# 设置为可用
load_template_source.is_usable = True
'books.zip_loader.load_template_source',
)
Django 自定义模版标签和过滤器的更多相关文章
- Django自定义模板标签和过滤器
		1.创建模板库 在某个APP所在目录下新建包templatetags,然后在其中创建存储标签或者过滤器的的模块,名称随意,例如myfilters.py. 在这个模块中编写相关代码. 注意:templa ... 
- Django 自定义模板标签和过滤器
		1.创建一个模板库 使用模板过滤器的时候,直接把过滤器写在app里,例如:在app里新建一个templatetags的文件夹,这个目录应当和 models.py . views.py 等处于同一层次. ... 
- django “如何”系列4:如何编写自定义模板标签和过滤器
		django的模板系统自带了一系列的内建标签和过滤器,一般情况下可以满足你的要求,如果觉得需更精准的模板标签或者过滤器,你可以自己编写模板标签和过滤器,然后使用{% load %}标签使用他们. 代码 ... 
- Django内建模版标签和过滤器
		第四章列出了许多的常用内建模板标签和过滤器.然而,Django自带了更多的内建模板标签及过滤器.这章附录列出了截止到编写本书时,Django所包含的各个内建模板标签和过滤器,但是,新的标签是会被定期地 ... 
- 模板继承and自定义模板标签和过滤器
		自定义模板标签和 过滤器: 因为模板标签和过滤器只给我们提供了 这么多 无法对我们的使用造成更多的便利 ,剩下的就需要我们自己去创建新的 模板标签和过滤器了 1.在settings中的INSTALLE ... 
- django 内建标签和过滤器参考
		下面的标签和过滤器参考就是为那些没有 admin 站点的可用的人准备的.由于 Django 是高度可定制的,你的 admin 里的关于标签和过滤器的参考可以认为是最可信的. 内建标签参考 block ... 
- django特殊的标签和过滤器
		国际化标签和过滤器 Django还提供了一些模板标签和过滤器,用以控制模板中国际化的每个方面.它们允许对翻译,格式化和时区转换进行粒度控制. 1. i18n 此标签允许在模板中指定可翻译文本.要启用它 ... 
- python 全栈开发,Day70(模板自定义标签和过滤器,模板继承 (extend),Django的模型层-ORM简介)
		昨日内容回顾 视图函数: request对象 request.path 请求路径 request.GET GET请求数据 QueryDict {} request.POST POST请求数据 Quer ... 
- Django 模板    语法    变量     过滤器    模板继承      组件     自定义标签和过滤器         静态文件相关
		本节目录 一 语法 二 变量 三 过滤器 四 标签Tags 五 模板继承 六 组件 七 自定义标签和过滤器 八 静态文件相关 一 语法 模板渲染的官方文档 关于模板渲染你只需要记两种特殊符号(语法 ... 
随机推荐
- L8,the best and the worst
			expressions: enter for 报名参加,只有作为参加的意思的时候才会用for enter the room进入房间 a little prize for the worst garde ... 
- 使用Java的BlockingQueue实现生产者-消费者
			http://tonl.iteye.com/blog/1936391 使用Java的BlockingQueue实现生产者-消费者 博客分类: Java JavaBlockingQueue阻塞队列 B ... 
- JavaBean-- 保存 范围
			1. page:当前页 2. request:一次服务器跳转范围中 3. session:一次用户操作范围,重新打开浏览器失效 4. application:整个服务器保存,服务器关闭才失效 定义一个 ... 
- Eclipse配置
			下载地址:http://www.eclipse.org/downloads/ tomcat plugin:http://www.eclipsetotale.com/tomcatPlugin.html# ... 
- 8数码,欺我太甚!<bfs+康拓展开>
			不多述,直接上代码,至于康拓展开,以前的文章里有 #include<iostream> #include<cstdio> #include<queue> using ... 
- PAT1011
			With the 2010 FIFA World Cup running, 随着2010世界杯的举行 football fans the world over were becoming increa ... 
- mknod用法以及主次设备号【转】
			转自:http://www.cnblogs.com/hnrainll/archive/2011/06/10/2077583.html mknod 用途 创建特殊文件. mknod Name { b | ... 
- Spring注入值得2种方式:属性注入和构造注入
			Spring是一个依赖注入(控制反转)的框架,那么依赖注入(标控制反转)表现在那些地方了? 即:一个类中的属性(其他对象)不再需要手动new或者通过工厂方法进行创建,而是Spring容器在属性被使用的 ... 
- python之路:进阶篇 内置函数
			li = [11, 22, 33] news = map( li = [100, 2200, 3300] news = map( [13, 24, 35] [11, 11, 11] [22, 4 ... 
- git fetch
			http://www.ruanyifeng.com/blog/2012/07/git.html 流程 默认情况下,git fetch取回所有分支(branch)的更新.如果只想取回特定分支的更新,可以 ... 
