2009-01-19 28 views
57

Django模板提供內置標記cycle,用於在模板中的不同點之間交替使用多個值(或用於模板中的循環),但此標記在其重置時不會重置在範圍之外的範圍內訪問。也就是說,如果您的模板中有兩個或更多列表,那麼您希望使用某些css定義oddeven的所有行,列表的第一行將會從最後一個離開的位置開始拾取,而不是從選擇新鮮的迭代(oddevenDjango模板中具有多行設置的替代行着色

例如,在下面的代碼,如果第一個博客有奇數個條目,然後在第二個博客的第一項將開始even,當我把它想從odd開始。

{% for blog in blogs %} 
    {% for entry in blog.entries %} 
    <div class="{% cycle 'odd' 'even' %}" id="{{entry.id}}"> 
     {{entry.text}} 
    </div> 
    {% endfor %} 
{% endfor %} 

我試着用這裏提供的resetcycle標籤修補此排除:

Django ticket: Cycle tag should reset after it steps out of scope

無濟於事。 (代碼沒有爲我工作。)

我也嘗試將我的內部循環移動到自定義標記,但這也沒有工作,也許是因爲編譯/渲染循環將循環移回到外部循環? (不管爲什麼,它不適合我。)

我該如何完成這個簡單的任務!?我不想用我預先編譯好的信息在我的視圖中創建數據結構;這似乎沒有必要。提前致謝。

回答

109

最簡單的解決辦法(直到resetcycle補丁被固定起來,並應用)是使用內置的「divisibleby」過濾器forloop.counter:

{% for entry in blog.entries %} 
    <div class="{% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}" id="{{ entry.id }}"> 
    {{ entry.text }} 
    </div> 
{% endfor %} 

有點冗長,但不難理解,它的效果很好。

1

最簡單的答案可能是:「放棄並使用jQuery」。如果這是可以接受的,那麼可能比使用Django的模板更容易。

+0

這是我做的,但因爲我是無論如何使用jQuery,這是相當微不足道的。 – 2009-01-20 04:06:35

2

放棄和使用Jinja2 Template System

我放棄了在Django的模板語言,它是非常的,你可以用它做什麼限制。 Jinja2使用的語法與django模板使用的相同,但增加了許多增強功能。我知道這聽起來像是一個很小的問題,但事實上我敢打賭,你總是發現自己在Django中與默認的模板系統對抗,所以它確實是值得的,我相信它從長遠來看,這會讓你的工作效率更高。)

你可以閱讀this article written by its author,儘管它是技術性的,但他提到了django中{%cycle%}標記的問題。

神社沒有一個週期的標籤,這對循環週期方法:

{% for user in users %} 
    <li class="{{ loop.cycle('odd', 'even') }}">{{ user }}</li> 
{% endfor %} 

的Jinja2的一個主要優點是,它可以讓你用邏輯的呈現,所以如果你有圖片列表,你可以把它們放在一個表,因爲你可以啓動一個表中的一個新行每N個元素,看到的,比如,你可以這樣做:

{% if loop.index is divisibleby(5) %} 
    </tr> 
    {% if not loop.last %} 
    <tr> 
    {% endif %} 
{% endif %} 

你也可以使用數學表達式:

{% if x > 10 %} 

,您可以直接訪問你的Python功能(但一些設置需要指定哪些職能應該暴露爲模板)

{% for item in normal_python_function_that_returns_a_query_or_a_list() %} 

即使設定變量..

{% set variable_name = function_that_returns_an_object_or_something() %} 
+2

對於這樣一個小問題,這是一個很大的轉變(伴隨着一些主要的複雜問題,如第三方或contrib應用程序)。 -1 – 2009-01-20 02:31:35

+3

提出的好點。問題是,我敢打賭,人們總是發現自己與Django模板系統發生衝突,這不僅僅是這個小問題,還有一個問題,那就是一堆煩惱。 – hasen 2009-01-20 03:34:01

+0

感謝您的建議和文章; Django的模板化方法讓我感到受到限制,並且受到它的bug的困擾。但是Django總體上很甜美。 – 2009-01-20 06:58:41

-5

有一種使用迭代器在服務器端執行的方法,該迭代器不會同時複製所有條目:

import itertools 
return render_to_response('template.html', 
    { 
    "flattened_entries": itertools.chain(*(blog.entries for blog in blogs)), 
    }) 
2

我最終這樣做,與forloop.counter0 - 它工程很棒!

{% for product in products %} 

    {% if forloop.counter0|divisibleby:4 %}<div class="clear"></div>{% endif %} 

    <div class="product {% if forloop.counter0|divisibleby:4 %}col{% else %}col20{% endif %}"> 
     Lorem Ipsum is simply dummy text 
    </div> 

{% endfor %}