【问题标题】:Splitting a list with django template tags使用 django 模板标签拆分列表
【发布时间】:2013-07-30 20:40:13
【问题描述】:

在我的上下文中,我有一个列表 my_list,我想将它呈现为两个“列”,第一列中的第一个 (n+1)/2 项和最后一个 n/2第二列中的项目。有没有一种直接的方法可以使用 django 模板标签/过滤器来做到这一点,或者我是否需要在我的视图中将列表预先分成两个?

例如,

<div class="split-50-left">
  <ul> 
    {% for item in [first half of my_list] %}
      <li>{{item}}</li>
    {% endfor %}
  </ul>
</div>
<div class="split-50-right">
  <ul> 
    {% for item in [second half of my_list] %}
      <li>{{item}}</li>
    {% endfor %}
  </ul>
</div>

【问题讨论】:

标签: django django-templates


【解决方案1】:

更“Django”的方式是在视图中执行此操作,因为您应该尽可能多地在模板之外保留逻辑。话虽如此,有一种方法可以通过模板来实现。

如果您已经知道列表中有多少,您可以使用slice template tag。假设你没有。

另一种方法是循环两次,只显示你想要的一半。不过,您每次都会遍历 整个 列表,因此可能会很昂贵。它使用forloop counter

{% for item in items %}
#half list is calculated in your view. It is the items query /2
   {% if forloop.counter < half_list %}
       {% item.name %}
   {% endif %}
{% endfor %}

{% for item in items %}
#half list is calculated in your view. It is the items query /2
    {% if forloop.counter >= half_list %}
        {% item.name %}
    {% endif %}
{% endfor %}

【讨论】:

  • 我正要说类似的话(关于它是在视图中更多的 Django 方式),但另一方面,这不是真正的显示逻辑吗? Django 说应该在模板中完成。
  • 好点。我一直试图在模板中保留尽可能多的逻辑,无论它是否显示。你被赋予了更多的权力,模板是如此的限制。
  • 完全是这样,在视图中做起来会容易得多。真是太糟糕了,模板语言是如此有限。有时显示逻辑确实需要实际的逻辑。
  • 正如你提到的,它看起来确实像“显示”逻辑,但考虑到模板语言的限制,我在视图中拆分列表并将其作为“left_items”放在上下文中“right_items”,因为无论如何我至少必须计算“half_list”或类似的东西。谢谢! left_items = items[:(len(items)+1)/2]right_items = items[(len(items)+1)/2:]
  • 根据标记的样子,您不必调用 forloop 两次,只需执行 {% if forloop.counter == half_list %},然后关闭第一个列表并在其中打开第二个列表。跨度>
【解决方案2】:

在模板中完全做到这一点的一种(有点笨拙的)方法是使用 widthratio 模板标签来计算列表的中心,并使用 with 模板标签来计算创建临时变量。

{% widthratio form.visible_fields|length 2 1 as visible_fields_centre %}
<div class="rows_form">
    {% with ":"|add:visible_fields_centre as first_slice %}
        {% for field in form.visible_fields|slice:first_slice %}
            {{ field }}
        {% endfor %}
    {% endwith %}
</div>
<div class="rows_form">
    {% with visible_fields_centre|add:":" as second_slice %}
        {% for field in form.visible_fields|slice:second_slice %}
            {{ field }}
        {% endfor %}
    {% endwith %}
</div>

【讨论】:

    【解决方案3】:

    如果您可以对两半进行插值 - 或者如果拆分中间并不重要 - 您可以分别渲染替代值。这会更便宜:

    <ul><!-- Half of the list -->
        {% for i in values %}
            {% cycle 'odd' 'even' as state silent %}
            {% if state == 'odd' %}
                <li>{{ i }}</li>
            {% endif %}
        {% endfor %}
    </ul>
    
    <ul><!-- The other half -->
        {% for i in values %}
            {% cycle 'odd' 'even' as state silent %}
            {% if state == 'even' %}
                <li>{{ i }}</li>
            {% endif %}
        {% endfor %}
    </ul>
    

    【讨论】:

      【解决方案4】:

      使用 css 是否有意义?我相信它会起作用everywhere except IE9

      <ul class="two-columns">
      {% for item in object_list %}
        <li>{{ item }}</li>
      {% endfor %}
      </ul>
      

      然后是css:

      ul.two-columns {
          -moz-column-count: 2;
          -webkit-column-count: 2;
          column-count: 2;
      }
      

      【讨论】:

        猜你喜欢
        • 2017-04-23
        • 2014-09-13
        • 2014-03-20
        • 2011-05-02
        • 2011-06-15
        • 2011-04-16
        • 1970-01-01
        • 2021-06-16
        • 2019-01-14
        相关资源
        最近更新 更多