Django / Python:在Django模板中循环选定的表单字段

时间:2011-12-13 07:28:48

标签: django forms templates for-loop

我有一个包含n个字段的表单。前4个字段应该在我的模板中以不同的形式显示。因此,我想知道我是否可以以某种方式循环前4个字段,结束循环并继续在模板中的其余字段上循环。

        <table>
            {% for field in form %}
            {% if forloop.counter == 4 <<< Break here >>>%}
            <tr>
                <td> {{ field.label_tag }} </td>
                <td> {{ field }} </td>
            </tr>
            {% endfor %}
        </table>
        .... Different code ....
        <table>
            {% for field in form %} <<< Continue here >>>
            <tr>
                <td> {{ field.label_tag }} </td>
                <td> {{ field }} </td>
            </tr>
            {% endfor %}
        </table>

我找到了this code,但我想知道我是否能够以不同的方式构建模板,或者我是否错过了Django 1.3中允许现在断开循环的一些新变化。

通常情况下,我会将表单分成两个单独的表单,但我也希望在其他模板中重用表单定义,因此我希望将所有信息保存在一个表单中。

感谢您的建议!

5 个答案:

答案 0 :(得分:8)

与其他“无法在模板中执行”问题的解决方案相同:在视图中执行此操作。我真的相信增加的复杂性和逻辑进一步分离到多个代码区域(标签,新文件等)只会损害可维护性。只有当事情确实变得重复,不可读等时,我才会分开/实施DRY。

其他一切都是过早的优化。

Django不会知道提交表单时的区别。

fields = list(form)    
part1, part2 = fields[:4], fields[4:]


{% for field in part1 %}{{ field }}{% endfor %}
...
{% for field in part2 %}{{ field }}{% endfor %}

答案 1 :(得分:2)

我建议你自己编写custom template。也许你的过滤器看起来像这样:

def show_part(form,section=1): 
    display = ''
    for id,field in enumerate(form):  
         if int(section) == 1 and id > 3:
             break
         elif int(section) == 2 and id < 3:
             continue
         display += '<tr><td>'+field.label_tag+'</td>'
         display += '<td>'+field+'</td></tr>'
    return display    

并在模板中使用以下内容:

<table>
    {{ form|show_part:"1" }}
</table>
<table>
    {{ form|show_part:"2" }}
</table>

答案 2 :(得分:2)

由于form是一个列表,你也可以使用Django的内置切片模板过滤器:https://docs.djangoproject.com/en/1.3/ref/templates/builtins/#slice

你的例子将成为:

    <table>
        {% for field in form|slice:":4" %}
        <tr>
            <td> {{ field.label_tag }} </td>
            <td> {{ field }} </td>
        </tr>
        {% endfor %}
    </table>
    .... Different code ....
    <table>
        {% for field in form|slice:"4:" %}
        <tr>
            <td> {{ field.label_tag }} </td>
            <td> {{ field }} </td>
        </tr>
        {% endfor %}
    </table>

答案 3 :(得分:1)

你几乎就在那里,如果你只是添加

<table>
{% if forloop.counter <= 4 %}
... first four fields
{% else %}
... other fields
{% endif %}

如果您需要两个不同的表格,可以添加:

{% if forloop.counter == 1 %}
<table>
{% endif %}

{% if forloop.last %}
</table>
{% endif %}

这不是一个非常漂亮的解决方案,但它确实有效。您还可以考虑使用两种形式。

答案 4 :(得分:0)

比Yuji&#39; Tomita&#39;更短。富田&#34;答案

在视图上列出表单:

context = {'form': list(form)}
return render(request, template, context)

并通过| slice

获取模板上的每个字段
{% for field in form|slice:":4" %}
    <tr>
        <td> {{ field.label_tag }} </td>
        <td> {{ field }} </td>
    </tr>
{% endfor %}