如何制作可变长度arg列表的django自定义模板标签

问题描述:

我正在写一个自定义模板标签'firstnotnone',类似于Django的'firstof'模板标签。如何使用可变长度参数?下面的代码导致TemplateSyntaxError,firstnotnone接受1个参数。如何制作可变长度arg列表的django自定义模板标签

模板:

{% load library %} 
{% firstnotnone 'a' 'b' 'c' %} 

自定义模板标签库:

@register.simple_tag 
def firstnotnone(*args): 
    print args 
    for arg in args: 
     if arg is not None: 
      return arg 

定制templatetags:

from django.template import Library, Node, TemplateSyntaxError 
from django.utils.encoding import smart_unicode 

register = Library() 

class FirstNotNoneNode(Node): 
    def __init__(self, vars): 
     self.vars = vars 

    def render(self, context): 
     for var in self.vars: 
      value = var.resolve(context, True) 
      if value is not None: 
       return smart_unicode(value) 
     return u'' 

def firstnotnone(parser,token): 
    """ 
    Outputs the first variable passed that is not None 
    """ 
    bits = token.split_contents()[1:] 
    if len(bits) < 1: 
     raise TemplateSyntaxError("'firstnotnone' statement requires at least one argument") 
    return FirstNotNoneNode([parser.compile_filter(bit) for bit in bits]) 

firstnotnone = register.tag(firstnotnone) 
+1

感谢,代码看上去干净。太糟糕了,它不能用可变长度的参数列表来完成。 – 2010-08-11 12:37:46

+0

你确定它不能? – MattH 2010-08-11 12:42:44

+0

@Jack Ha:它处理可变长度参数列表,我甚至测试过它。据我所知,这是一个你正在要求的实现。 – MattH 2010-08-11 13:22:33

firstof标签不通过simple_tag装饰来实现 - 它采用了template.Node子和一个单独的标签的长形功能。您可以在django.template.defaulttags中看到代码 - 为了您的目的而进行更改应该相当简单。