【问题标题】:ForLoop Iterations as List Index in Django TemplateForLoop 迭代作为 Django 模板中的列表索引
【发布时间】:2012-01-19 19:54:56
【问题描述】:

我正在构建一个 django 网页,但我似乎遇到了障碍,因为我真的不知道如何将当前的 for 循环迭代(在模板中)用于多个列表:

        {% for num in loopRange %}
    <tr>
        {% for num2 in subRange %}
        <td>{% cycle list1 list2 list3 list4 %}</td>
        {% endfor %}
    </tr>
    {% endfor %}

我在 stackoverflow 发现了几个类似的问题,我尝试使用循环,但这只是导致每次都打印列表的所有成员——这并不完全出乎意料,但我不知道如何我的生活。

我拥有的是多个内容相似的列表,每个列表都是一行中的一列。所以,如果它是 python 并且我正在连接字符串,它会是这样的:

for i in xrange(5):
    string = list1[i] + list2[i] + list3[i] + list 4[i]

基本上就是这样。除了两个 xrange(第一个示例中的 loopRange 和 Subrange)之外,我还将每个列表作为上下文传递,我需要五行(每个列表有五个成员)和四列(四个列表)。

编辑:我想简而言之,我想将列表索引称为 foo[bar],在 django 中作为 foo.bar 完成,但是 bar 显然不能是作为内容传入的可迭代范围的整数

谢谢!

【问题讨论】:

    标签: python django loops


    【解决方案1】:

    我想说最好的方法是在将视图中的数据传递给模板之前对其进行处理。

    例如,zip 内置函数可用于根据包含列的列表创建行列表:

    rows = zip(list1, list2, list3, list4)
    

    之后,模板可以逐行遍历行,并在需要时使用索引访问来访问列:

    {% for row in rows %}
      {{row.0}} {{row.1}} {{row.2}} {{row.3}}
    {% endfor %}
    

    【讨论】:

    • 解决了!极好的。 zip() 是一个非常方便的函数。
    【解决方案2】:

    您可以创建一个简单的过滤器来从列表中返回一个项目:

    @register.filter
    def get_item(row, i):
        try:
            return row[i]
        except IndexError:
            return ''
    

    然后:

    {{ list1|get_item:num2 }}
    

    【讨论】:

      【解决方案3】:

      如果您出于某种原因真的想在自己的模板中执行此操作,您还可以编写一个 custom template tag 来为您完成此操作:

      #app/templatetags/zip.py
      from django import template
      
      register = template.Library()
      
      class Zipper(template.Node):
          def __init__(self, format_string, var_name):
              self.format_string = format_string
              self.var_name = var_name
          def render(self, context):
              zippables = [context[tok] for tok in self.format_string.split()]
              import pdb; pdb.set_trace()
              context[self.var_name] = zip(*zippables)
              return ''
      
      import re
      
      @register.tag(name="zip")
      def do_zip(parser, token):
          try:
              # Splitting by None == splitting by spaces.
              tag_name, arg = token.contents.split(None, 1)
          except ValueError:
              raise template.TemplateSyntaxError("%r tag requires arguments" % token.contents.split()[0])
          m = re.search(r'(.*?) as (\w+)', arg)
          if not m:
              raise template.TemplateSyntaxError("%r tag had invalid arguments" % tag_name)
          format_string, var_name = m.groups()
          return Zipper(format_string, var_name)
      

      注意:由于添加了assignment_tag,此语法在 Django 1.4 中将变得更加简单。

      然后,像这样使用它:

      {%load zip%}
      
      {% zip list1 list2 list3 list4 as list_of_rows %}
      

      然后,您可以在该块中的任何位置使用list_of_rows,包括在两个嵌套的 for 循环内。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-10
        • 2021-10-28
        • 2016-06-26
        • 1970-01-01
        • 2019-03-05
        • 1970-01-01
        • 2014-08-19
        相关资源
        最近更新 更多