这两天写qm工具,需要在模板上使用类似 switch...case...else的逻辑,baidu发现django15居然木有,无奈之下找了个差不多的,自己改之,共享出来,给有同样需求的同学
__author__ = 'cdxfish'
#coding=utf-8
from django import template
from django.template.base import NodeList,Node
register = template.Library()
'''
{% load switchcase %}
{% switch condition %}
{% case "a" %} if condition==a do .. {% endcase %}
{% case "b" %} if condition==b do .. {% endcase %}
{% else %}
if condition != a and condition != b....
{% endswitch %}
'''
@register.tag
def switch(parser, token):
args=token.split_contents()
if len(args) != 2:
raise template.TemplateSyntaxError('%s exactly takes 2 args'% args[0])
nodelist_true = parser.parse(('else', 'endswitch',))
nodelist_true = nodelist_true.get_nodes_by_type(CaseNode)
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse(('endswitch',))
parser.delete_first_token()
else:
nodelist_false = NodeList()
return SwitchNode(args[1], nodelist_true, nodelist_false)
@register.tag
def case(parser, token):
args=token.split_contents()
if len(args) != 2:
raise template.TemplateSyntaxError('%s exactly takes 2 args'% args[0])
children= parser.parse(('endcase',))
parser.delete_first_token()
return CaseNode(args[1],children)
class SwitchNode(template.Node):
def __init__(self, value, nodelist_true, nodelist_false):
self.value=value
self.nodelist_true=nodelist_true
self.nodelist_false=nodelist_false
def render(self, context):
try:
value = template.resolve_variable(self.value,context)
except template.VariableDoesNotExist:
return ""
for case in self.nodelist_true:
if case.equals(value, context):
return case.render(context)
ret=[]
for es in self.nodelist_false:
ret.append(es.render(context))
return ''.join(ret)
class CaseNode(template.Node):
def __init__(self, value, childnodes):
self.value = value
self.childnodes=childnodes
def equals(self, otherval, context):
try:
return template
.resolve_variable(self.value ,context) == otherval
except template.VariableDoesNotExist:
return False
def render(self, context):
return self.childnodes.render(context)