【问题标题】:pass a list as a parameter to django tag将列表作为参数传递给 django 标签
【发布时间】:2019-02-03 03:09:55
【问题描述】:

我在 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' %}

但我想知道是否有更好的方法来处理这个问题。

【问题讨论】:

  • 您不能为此使用*args 吗?那么头部的位置参数呢?提供有关my_tag 的更多详细信息可能会有所帮助。
  • 作为答案发布,因为我是新来的,没有足够的声誉发布评论。但这只是上面answer 的补充。字符串文字上的 Split() 对我不起作用,出现解析错误,但在变量中捕获字符串然后使用 split() 有效 {% with listparams_literal='XY Z' %} {% my_tag paramA='asdf' paramB ='fdsa' listparams=listparams_literal.split %}

标签: django django-templates django-template-filters


【解决方案1】:

这里基本上有两种方法:

  1. 试图以一种或另一种方式构造一个列表,并将其传递给my_tag;或
  2. 更改my_tag 以便传递列表更方便。

构建列表

Django 模板提供了构建列表的方法,尽管其中大部分都相当有限。

使用make_list 模板过滤器

例如,Django 引入了一个make_list template filter [Django-doc],它接受一个可迭代对象,并将其转换为项目列表。例如,我们可以使用模板过滤器:

{% my_tag paramA='asdf' paramB='fdsa' listparams=<b>'XY'|make_list</b> %}

但是这样做有两个潜在的问题:(1)对于一个字符串,它遍历字符,所以元素都是 1 字符的字符串,以及(2)你不能构造包含整数的列表等。除非你已经有一个类似集合的对象,但这基本上会使make_list 无用。

使用.split()

我们可以通过调用.split()来解决它只需要1个字符的字符串的问题,这仅适用于字符串(除非变量的类型也支持.split()函数),所以我们可以解决多字符部分的问题:

{% my_tag paramA='asdf' paramB='fdsa' listparams=<b>'XY Z'.split</b> %}

实现自定义可变参数标签来构造列表

我们还可以定义一个可变参数标签,它首先构造一个列表。我们通过实现一个自定义标签来做到这一点:

#  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 <b>'X' 'Y'</b> 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

这种方法的一个潜在问题是我们只能执行这个“技巧”一次,因为我们不能定义两个单独的*args。我们当然可以将*args 拆分为两个列表,但这可能很棘手。

【讨论】:

    猜你喜欢
    • 2014-10-28
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 2021-06-01
    • 2019-03-02
    • 1970-01-01
    • 2012-03-07
    相关资源
    最近更新 更多