2011-12-13 37 views
1

我有一個帶有n個域的表單。前四個字段應該以不同的方式顯示在我的模板中,然後是表單的其餘部分。因此,我想知道是否可以以某種方式循環播放前四個字段,結束循環並在模板中稍後繼續循環播放其餘字段。Django/Python:在Django模板中循環選定的表單域

 <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的一些新變化,允許環的斷裂了。

通常情況下,我會分裂形式在兩個不同的形式,但我想重用在其他模板的形式定義爲好,所以我想以某種形式保持在一起的所有信息。

謝謝您的建議!

回答

8

它與其他「在模板中無法實現」問題的解決方案相同:在視圖中執行此操作。我真的相信增加複雜性和將邏輯進一步分離到多個代碼區域(標籤,新文件等)只會傷害可維護性。我分開/只實現DRY當事情其實也得到重複,無法讀取等

其他的都是不成熟的優化。

Django在提交表單時不會知道區別。

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


{% for field in part1 %}{{ field }}{% endfor %} 
... 
{% for field in part2 %}{{ field }}{% endfor %} 
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> 
1

就快,如果你只需要添加

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

如果您需要兩個不同的表,你可以添加:

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

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

這不是一個非常漂亮的解決方案,但它的工作原理。你也可以考慮使用兩種形式。

1

因爲形式是一個列表,你也可以使用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> 
+1

的工作?我試過你的解決方案,但不適用於我。但是我改進了一次代碼片段{%for field in form.visible_fields | slice:「:4」%}''併爲我工作。 –

0

比「虞姬‘富田’富田短在您的視圖「回答

的形式使列表:

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

,並通過獲得模板的每個字段|切片

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