我不知道是否可能,但我希望能够写出如下内容:
{% with var1 var2 var3 as some_list %}
{{ some_list|maximum }}
{% endwith %}
从任意数量的模板变量和/或文字中动态创建列表似乎很有用,所以我希望我忽略了一些简单的事情。
如果不这样做,我想知道如何创建一个接受任意数量参数的模板标签。 (我玩过simple_tag
,它适用于接受固定数量参数的标签。)
在确定没有更简单的解决方案之前,我不想去创建解析器和继承django.template.Node
的麻烦。
答案 0 :(得分:15)
如果您想添加新变量(即some_list
),则需要访问模板的上下文,因此simple_tag
是不够的。
对我来说,第一种方法是尝试在视图中执行此类工作,以使模板尽可能简单。
如果这不合适,您必须手动编写标签,如下所示:
@register.tag
def make_list(parser, token):
bits = list(token.split_contents())
if len(bits) >= 4 and bits[-2] == "as":
varname = bits[-1]
items = bits[1:-2]
return MakeListNode(items, varname)
else:
raise template.TemplateSyntaxError("%r expected format is 'item [item ...] as varname'" % bits[0])
class MakeListNode(template.Node):
def __init__(self, items, varname):
self.items = map(template.Variable, items)
self.varname = varname
def render(self, context):
context[self.varname] = [ i.resolve(context) for i in self.items ]
return ""
并像这样使用它来创建一个新变量some_list
:
{% make_list var1 var2 var3 as some_list %}
随意给它一个更好的名字!
答案 1 :(得分:3)
我玩了一下,想出了一个可以接受可变数量的参数并将它们转换成列表的标签。
@register.tag('to_list')
def to_list(_parser, token):
try:
parts = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, \
"%r tag requires at least one argument" % token.contents.split()[0]
return AsListNode(parts[1:])
class AsListNode(template.Node):
def __init__(self, parts):
self.parts = map(lambda p: template.Variable(p), parts)
def render(self, context):
resolved = []
for each in self.parts:
resolved.append(each.resolve(context))
return resolved
模板:
<p>{% to_list var1 var2 var3 %}</p>
<强>更新强>
@ Will solution更好。它允许您使用另一个变量保存结果列表,以便以后可以对其进行操作。