参考文章:

http://xiao80xiao.iteye.com/blog/519394 (django 自定义标签和过滤器)

http://www.cnblogs.com/btchenguang/archive/2012/09/05/2672364.html#WizKMOutline_1346841868165594 (Django框架学习-Templates进阶用法--下)



自定义标签放在app/templatetags下。下面是3个例子。


自定义标签1(过滤器):

vim test_tags.py

from django.template import Library
register = Library()

@register.filter('percent_decimal')
def percent_decimal(value):
    value = float(str(value))
    value = round(value, 3)
    value = value * 100

    return str(value) + '%'

#register.filter('percent_decimal', percent_decimal)

作用是将传过来的小数转换成百分比显示

views.py

def test(request):
    return render_to_response('test.html')

test.html

{% load test_tags %}
{{ 12.09|percent_decimal}}

前端显示:

wKiom1S4xsySLrVbAAA9jWPORW0001.jpg


自定义标签2

vim mytag.py

from django import template
register = template.Library()

@register.tag(name='mytag')
def do_parse(parser,token):
    try:
        tag_name,format_string = token.split_contents()
    except:
        raise template.TemplateSyntaxError("tag error!")
    return Mytag(format_string[1:-1])

class Mytag(template.Node):
    def __init__(self, format_string):
        self.format_string = format_string
    def render(self, context):
        return self.format_string


views.py

def test2(request):
    return render_to_response('test2.html')


test2.html

<html>
<body>
{% load mytag %}
{% mytag 'excellent!' %}
</body>
</html>


前端显示:

wKiom1S4x9qjNj3pAAA_uSxBonI207.jpg


自定义标签3

vim currenttime_tag.py

from django import template
import datetime
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)
    
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)


views.py

def test3(request):
    return render_to_response('test3.html')


test3.html

<html>
<body>
{% load currenttime_tag %}
{% current_time "%Y-%m-%d %I:%M %p" %}
</body>
</html>


前端显示:

wKiom1S4yVDj7IMMAABLPzCVceE193.jpg


自定义标签4(在上下文中设置变量):

vim context_tga.py

import re
from django import template
import datetime
register = template.Library()

class CurrentTimeNode(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):
    try:
        tag_name,arg = token.contents.split(None, 1)
    except ValueError:
        msg = '%r tag requires a single argument' % token.split_contents()[0]
        raise template.TemplateSyntaxError(msg)
    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)        
    return CurrentTimeNode(fmt[1:-1], var_name)

register.tag('get_current_time', do_current_time)


views.py

def test4(request):
    return render_to_response('test4.html')


test4.html

<html>
<body>
{% load context_tag %}
{% get_current_time "%Y-%m-%d %I:%M %p" as my_current_time %}
<p>The current time is {{ my_current_time }}.</p>
</body>
</html>


前端显示

wKioL1S8cbqSizbvAABUof3Vk9U282.jpg


自定义标签5(大写)

vim upper_tag.py

from django import template
register = template.Library()

def do_upper(parser, token):
    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()

register.tag('upper', do_upper)


views.py

def test5(request):
    return render_to_response('test5.html')


test5.html

<html>
<body>
{% load upper_tag %}
<p>The current time is 2015-01-19 09:57 AM.</p>
{% upper %}<p style='color:orange'>The minute you think of giving up, think of the reason why you held on so long.</p> {% endupper %}
</body>
</html>


前端显示

wKioL1S8ckug8DAjAADYrDVthdQ417.jpg


自定义标签6(简单标签):

vim simple_tag.py

from django import template
import datetime
register = template.Library()

@register.simple_tag
def simple_time(format_string):
    try:
        return datetime.datetime.now().strftime(str(format_string))
    except UnicodeEncodeError:
        return ''


test6.html

<html>

<body>

{% load simple_tag %}

{% simple_time '%Y-%m-%d %I:%S %p' %}

</body>

</html>


前端显示

wKioL1S8nJjCq3m4AABPnMsJiX0548.jpg


自定义标签7(包含标签):

参考文章 http://blog.163.com/lyjlyj517@126/blog/static/16686350120133265235891/


解释:包含标签(inclution tag)的主要思路是当前模板通过使用其他模板显示数据。

通过@register.inclusion_tag('book_snippet.html') 注册包含标签,在def books_for_title中定义数据的获得方式,在'book_snippet.html'中定义显示方式。

使用时,{% books_for_title titlequery %},前者指示需要调用的自定义函数books_for_title,后者为传给books_for_title函数的参数。


vim inclusion_tag.py

from django import template
from books.models import Book

register = template.Library()

@register.inclusion_tag('book_snippet.html')
def books_for_title(titlequery):
    books = Book.objects.filter(title=titlequery)
    return {'books': books}


views.py

def test7(request):
    return render_to_response('result_snippet.html')


book_snippet.html

<ul>
{% for book in books %}
	<li>{{ book.title }}</li>
	<li>{{ book.publisher }}</li>
{% endfor %}
</ul>


result_snippet.html

<html>
<body>
{% load inclusion_tag %}
{% books_for_title 'A Plan' %}
{% books_for_title 'The romance of The Three Kingdoms' %}
</body>
</html>


前端显示

wKioL1S8yFHxCXREAABzO3FocDo583.jpg