如何在Django模板中使用变量索引访问列表?

时间:2021-05-09 22:56:38

Say, I have two lists of objects, foo and bar. In a Django template, while looping through foo, there's a counter that keeps track of the current index/iteration and the counter is used to access bar. The problem here is I don't think Django template system supports accessing list using variable indexes. Is that true? If so, is there any workaround for the problem (other than repeating the same piece of html/template code with hard-coded indexes)?

说,我有两个对象列表,foo和bar。在Django模板中,在循环遍历foo时,有一个计数器跟踪当前索引/迭代,计数器用于访问bar。这里的问题是我不认为Django模板系统支持使用变量索引访问列表。真的吗?如果是这样,问题是否有任何解决方法(除了用硬编码索引重复相同的html /模板代码)?

Code demonstration:

代码演示:

{% for x in foo %}
  <span>{{ x.name }} vs. {{ bar.{{ forloop.counter0 }}.name }}</span>
{% endfor %}

Django template doesn't like {{ bar.{{ forloop.counter0 }}.name }}

Django模板不喜欢{{bar。{{forloop.counter0}}。name}}

Note: I am using Django 1.4

注意:我使用的是Django 1.4

2 个解决方案

#1


6  

Right, you can't resolve variable names. Definitely try very hard to put this logic in the view.

对,你无法解析变量名。绝对要非常努力地将这个逻辑放在视图中。

But 5% of the time, I do find this extremely limiting at times requiring too much logic in the view / changes required outside the template authors control. I've come to accept a few personal customizations, allowing for variable assignment within the view as well as simple variable resolution.

但有5%的时间,我确实发现这极其有限,有时需要在模板作者控制之外的视图/更改中需要太多逻辑。我接受了一些个人定制,允许在视图中进行变量赋值以及简单的变量分辨率。

It's quite simple to build a template tag that does so though, using the template engines "all lookups in one" system (index, attribute, key).

尽管如此,使用模板引擎“所有查找在一个”系统(索引,属性,键)中构建模板标签非常简单。

from django.template import Variable, VariableDoesNotExist

@register.assignment_tag()
def resolve(lookup, target):
    try:
        return Variable(lookup).resolve(target)
    except VariableDoesNotExist:
        return None

{% resolve some_list some_index as value %}
{% resolve some_dict some_dict_key as value %}

#2


10  

You are correct that Django templates do not directly allow this, and it's because Django tries to force you to put pretty much all your presentation logic in your views. Your best option is to make a list of dicts in your context in your view, so you can iterate of that and access the members by name. Or:

你是正确的Django模板不直接允许这样做,这是因为Django试图强迫你在你的视图中放置几乎所有的表示逻辑。您最好的选择是在视图中创建上下文中的dicts列表,以便您可以迭代它并按名称访问成员。要么:

  • zip your lists together instead of making them a dict and access them using {% for fooItem, barItem in zippedList %}.
  • 将您的列表压缩在一起而不是使它们成为dict并使用{%for fooItem,zipIList中的barItem}来访问它们。
  • use a less limiting templating language, like Jinja2
  • 使用限制较少的模板语言,如Jinja2
  • use a custom template filter, as suggested by Yuji Tomita
  • 使用Yuji Tomita建议的自定义模板过滤器

#1


6  

Right, you can't resolve variable names. Definitely try very hard to put this logic in the view.

对,你无法解析变量名。绝对要非常努力地将这个逻辑放在视图中。

But 5% of the time, I do find this extremely limiting at times requiring too much logic in the view / changes required outside the template authors control. I've come to accept a few personal customizations, allowing for variable assignment within the view as well as simple variable resolution.

但有5%的时间,我确实发现这极其有限,有时需要在模板作者控制之外的视图/更改中需要太多逻辑。我接受了一些个人定制,允许在视图中进行变量赋值以及简单的变量分辨率。

It's quite simple to build a template tag that does so though, using the template engines "all lookups in one" system (index, attribute, key).

尽管如此,使用模板引擎“所有查找在一个”系统(索引,属性,键)中构建模板标签非常简单。

from django.template import Variable, VariableDoesNotExist

@register.assignment_tag()
def resolve(lookup, target):
    try:
        return Variable(lookup).resolve(target)
    except VariableDoesNotExist:
        return None

{% resolve some_list some_index as value %}
{% resolve some_dict some_dict_key as value %}

#2


10  

You are correct that Django templates do not directly allow this, and it's because Django tries to force you to put pretty much all your presentation logic in your views. Your best option is to make a list of dicts in your context in your view, so you can iterate of that and access the members by name. Or:

你是正确的Django模板不直接允许这样做,这是因为Django试图强迫你在你的视图中放置几乎所有的表示逻辑。您最好的选择是在视图中创建上下文中的dicts列表,以便您可以迭代它并按名称访问成员。要么:

  • zip your lists together instead of making them a dict and access them using {% for fooItem, barItem in zippedList %}.
  • 将您的列表压缩在一起而不是使它们成为dict并使用{%for fooItem,zipIList中的barItem}来访问它们。
  • use a less limiting templating language, like Jinja2
  • 使用限制较少的模板语言,如Jinja2
  • use a custom template filter, as suggested by Yuji Tomita
  • 使用Yuji Tomita建议的自定义模板过滤器