我在Django中有一个自定义包含标签,我需要在此处传递一个列表作为参数。遵循以下原则:
{% my_tag paramA='asdf' paramB='fdsa' listparams=['X', 'Y'] %}
这当然是行不通的,因为Django不知道如何处理以这种方式传递的列表。
我还可以捕获诸如list_
之类的通用内容,然后将它们组合到服务器端的列表中:
{% my_tag paramA='asdf' paramB='fdsa' list_1='X' list_2='Y' list_3='Z' %}
但是我想知道是否有更好的方法来解决这个问题。
答案 0 :(得分:2)
这里基本上有两种方法:
my_tag
;或my_tag
,以便传递列表更加方便。Django模板提供了构造列表的方法,尽管其中大多数都是相当有限的。
make_list
模板过滤器 Django引入了一个make_list
template filter [Django-doc],它接受一个可迭代的并将其转换为项目列表。例如,我们可以将模板过滤器用于:
{% my_tag paramA='asdf' paramB='fdsa' listparams='XY'|make_list %}
但这有两个潜在的问题:(1)对于在字符上迭代的字符串,因此元素都将是1个字符的字符串,(2)您不能构造包含整数的列表,等等。除非您已经有一个类似集合的对象,但这基本上会使make_list
失去作用。
.split()
我们可以通过执行对.split()
的调用来解决仅包含1个字符的字符串的问题,这仅适用于字符串(除非变量的类型也支持.split()
函数) ,因此我们可以通过以下方式解决多字符部分的问题:
{% my_tag paramA='asdf' paramB='fdsa' listparams='XY Z'.split %}
我们还可以定义一个可变标记,该标记首先构造一个列表。为此,我们实现了一个自定义标签:
# app/templatetags/create_list.py
from django import template
register = template.Library()
@register.simple_tag
def create_list(*args):
return args
然后我们可以使用两个步骤来传递列表:
{% load create_list %}
{% create_list 'X' 'Y' as mylist %}
{% my_tag paramA='asdf' paramB='fdsa' listparams=mylist %}
my_tag
也许一种干净的方法是在这里使用 positional 参数来获取列表。 Python中的函数具有两种类型的参数: positional 参数(在没有参数名称的情况下通过传递的参数)和 named 参数(带有key=...
的文件。
因此,我们可以在此处将位置标记用于列表,并使用以下代码调用标记:
{% my_tag 'X' 'Y' paramA='asdf' paramB='fdsa' %}
如果我们不提及任何位置参数,则该列表被认为是空的。我们可以传递任意数量的参数。
例如,我们可以将标签实施为:
# app/templatetags/my_tag.py
from django import template
register = template.Library()
@register.simple_tag
def my_tag(*listparams, paramA=None, paramB=None):
# ... processing
return None
这种方法的潜在问题是,在无法定义两个单独的*arg
的意义上,我们只能执行一次“技巧”。我们当然可以将*args
分成两个列表,但这可能很棘手。