在Django模板中将循环变量用作字典键

时间:2011-09-26 15:40:41

标签: django templates variables dictionary for-loop

我正在努力让以下工作。

计数循环需要遍历所有值,并且可能没有与每个计数关联的用户,但需要在每个循环中使用计数值i来传递给JavaScript。

python部分:

users = {}
users[1]={}
users[1][id]=...
users[1][email]=...

...

count=[1,2,3,4,5,6,7,8,9,10]

Django模板部分:

{% for i in count %}
do some stuff with the value i using {{i}} which always returns the value, i.e. 1

email:{% if users.i.email %}'{{users.i.email}}'{% else %}null{% endif%}
{% endfor %}

这不会为电子邮件返回任何内容。 当我在1电子邮件中替换i的号码{% if user.i.email %}时,会返回用户的电子邮件地址。 我在JavaScript中使用数据,因此如果它不存在则需要隐式为null。 我似乎无法让Django将i变量识别为变量而不是值i。

使用[]不起作用,因为它会引发无效的语法错误

email:{% if users.[i].email %}'{{users.[i].email}}'{% else %}null{% endif%}

我尝试过使用“with”声明

{% for i in count %}{% with current_user=users.i %}...

然后使用current_user.email,但没有返回任何内容

还试过

{% for i in count %}{% with j=i.value %}...

以防万一它会起作用,然后尝试使用j,但结果相同。

我已经考虑过创建一个内部for循环,它循环遍历用户对象并检查我是否等于键/值,但这看起来很昂贵且不太可扩展。

我是如何强制Django将i视为变量并将其值作为索引或以其他方式解决此问题的任何想法?

由于

Jayd

* 修改

我按照下面Abhi的建议尝试了额外的for循环。

{% for i in count %}
  {% for key, current_user in users.items %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
  {% endfor %}
{% endfor %}

此类工作,但现在它将为每个用户值重复do some stuff with the value i。如果我输入if:

{% for i in count %}
  {% for key, current_user in users.items %}
    {% if i == key %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}
    {% endif%}
  {% endfor %}
{% endfor %}

当计数没有特定用户时忽略循环。

我能看到的唯一方法就是在每个地方都有用户循环current_user

{% for i in count %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:{% for key, current_user in users.items %}{% if i == key and current_user.email %}'{{current_user.email}}'{% else %}null{% endif%}{% endfor %}
{% endfor %}

这看起来非常昂贵。 有什么想法吗?

我在考虑编写一个过滤器,该过滤器使用i作为键返回用户的值:

{% with current_user=users|getuser:i %}

但是我不知道这是否会起作用或者我会得到同样的错误,其中i作为值'i'而不是变量名传递。

我会试试这么久。

*的修改

这不起作用。 过滤器使用{{}}返回对象,但它在{% %}内部无效

感谢输入

4 个答案:

答案 0 :(得分:9)

正如Joe在评论中所说,字典显然是外容器的错误数据结构。你应该使用一个列表。

users = []
user = {'id':..., 'email': ...}
users.append(user)

...

{% for user in users %}
    {{ user.email }}
{% endfor %}

如果您需要循环中每个用户的数量,可以使用{{ forloop.counter }}

答案 1 :(得分:1)

试试这个:

{% for key,val in user.items %}
ID is {{ val.id }} and Email is {{ val.email }}
{% endfor %}

答案 2 :(得分:1)

我提出了以下解决方法:

这是过滤器代码:

@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
    if key in dict:
        return dict[key]
    else:
        return 'null'

这是模板代码

{% for i in count %}
      do some stuff with the value i using {{i}} which always returns the value, i.e. 1
      email:'{{users|dict_value_or_null:i|dict_value_or_null:'email'}}'
{% endfor %}

这很好用,所以我想有我的解决方案。但是我仍然认为,如果模板系统中有一种方法可以强制{%%}内的值被视为变量而不是文字,那么这一切都会变得容易得多。

有办法做到这一点吗?

感谢输入

答案 3 :(得分:1)

使Jayd代码可以使用list或dict,试试这个

@register.filter(name='dict_value_or_null')
def dict_value_or_null(dict, key):
    try:
        return dict[key]
    except:
        return 'null'